first pass at an Antora conversion

This commit is contained in:
Brian (bex) Exelbierd 2018-09-20 11:29:31 +02:00
parent 2e8934be40
commit f7cf94cd4c
193 changed files with 246 additions and 29224 deletions

3
.gitignore vendored Normal file
View file

@ -0,0 +1,3 @@
build
cache
public

View file

@ -7,11 +7,10 @@ include src/src.mk
#build: build-src build-manual
build-snippets:
mkdir -p en-US/snippets
mkdir -p modules/ROOT/pages/_partials/snippets
python scripts/split-snippets.py . \
src/*.c src/*.cpp src/*.java src/*.py src/*.go src/*.sh
clean: clean-src
-rm -rf html
-rm -rf en-US/*/snippets
-rm -rf modules/ROOT/pages/_partials/snippets

View file

@ -17,10 +17,79 @@ repository) at:
you lack the necessary libraries, the code examples are still
included in the manual.
After this you need to run `asciibinder package` to produce the document.
## Local preview
This repo includes scripts to build and preview the contents of this repository.
# Dependencies
**NOTE**: Please note that if you reference pages from other repositoreis, such links will be broken in this local preview as it only builds this repository. If you want to rebuild the whole Fedora Docs site, please see [the Fedora Docs build repository](https://pagure.io/fedora-docs/docs-fp-o/) for instructions.
Building the manual pages needs the "publican" and the "publican-fedora"
packages.
Both scripts use docker, so please make sure you have it installed on your system. Please see below for instructions.
To build and preview the site, run:
```
$ ./build.sh && ./preview.sh
```
The result will be available at http://localhost:8080
### Installing docker on Fedora
```
$ sudo dnf install docker
$ sudo systemctl start docker && sudo systemctl enable docker
```
### Preview as a part of the whole Fedora Docs site
You can also build the whole Fedora Docs site locally to see your changes in the whole context.
This is especially useful for checking if your `xref` links work properly.
To do this, you need to clone the main [Fedora Docs build repository](https://pagure.io/fedora-docs/docs-fp-o), modify the `site.yml` file to reference a repo with your changes, and build it.
Steps:
Clone the main repository and cd into it:
```
$ git clone https://pagure.io/fedora-docs/docs-fp-o.git
$ cd docs-fp-o
```
Find a reference to the repository you're changing in the `site.yml` file, and change it so it points to your change.
So for example, if I made a modification to the Modularity docs, I would find:
```
...
- url: https://pagure.io/fedora-docs/modularity.git
branches:
- master
...
```
And replaced it with a pointer to my fork:
```
...
- url: https://pagure.io/forks/asamalik/fedora-docs/modularity.git
branches:
- master
...
```
I could also point to a local repository, using `HEAD` as a branch to preview the what's changed without the need of making a commit.
**Note:** I would need to move the repository under the `docs-fp-o` directory, because the builder won't see anything above.
So I would need to create a `repositories` directory in `docs-fp-o` and copy my repository into it.
```
...
- url: ./repositories/modularity
branches:
- HEAD
...
```
To build the whole site, I would run the following in the `docs-fp-o` directory.
```
$ ./build.sh && ./preview.sh
```

View file

@ -1,11 +0,0 @@
---
fedora:
name: Defensive Coding Guide
author: Fedora Docs <docs@lists.fedoraproject.org>
site: main
site_name: Home
site_url: https://docs.fedoraproject.org/
branches:
master:
name:
dir: master

View file

@ -1,135 +0,0 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<!-- The above 3 meta tags *must* come first in the head; any other head content must come *after* these tags -->
<title>Fedora Documentation Website</title>
<!-- Bootstrap -->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css">
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap-theme.min.css">
<link rel="stylesheet" href="https://overpass-30e2.kxcdn.com/overpass.css">
<link rel="stylesheet" href="_stylesheets/asciibinder.css">
<!-- HTML5 shim and Respond.js for IE8 support of HTML5 elements and media queries -->
<!-- WARNING: Respond.js doesn't work if you view the page via file:// -->
<!--[if lt IE 9]>
<script src="https://oss.maxcdn.com/html5shiv/3.7.2/html5shiv.min.js"></script>
<script src="https://oss.maxcdn.com/respond/1.4.2/respond.min.js"></script>
<![endif]-->
</head>
<body>
<div class="container">
<div class="row">
<div class="page-header">
<img src="/_images/fedora.svg" class="img-responsive" />
<h2><strong>Fedora Documentation Site</strong></h2>
</div>
</div>
<div class="row">
<div class="col-md-8">
<h4><strong>Fedora Documentation - 404 Page Not Found :(</strong></h4>
<p>Hi! You've arrived at Fedora documentation page which does not actually exist. This may be because you followed a link to an older document which has been retired. For reference, you can find those in our <a href="https://docs-old.fedoraproject.org/">old document archive</a>. Or, you can browse <a href="https://docs.fedoraproject.org/">current docs</a>.</p>
<p>It may also be that this page _should_ exist, but sadly does not. If this is the case, and you know what it should say, you can <a href="https://pagure.io/fedora-docs">contribute via the Docs Project</a>.</p>
</div>
</div>
</div>
</div>
<div id="bottom" class="text-muted py-3" >
<div class="foot">
<div class="container">
<div class="row footerlinks">
<div class="col-sm-3 col-xs-6 widget">
<h3 class="widget-title">About</h3>
<div class="widget-body">
<dl>
<dd><a href="https://fedoraproject.org/wiki/Overview">About Fedora</a></dd>
<dd><a href="https://getfedora.org/en/sponsors">Sponsors</a></dd>
<dd><a href="https://fedoramagazine.org">Fedora Magazine</a></dd>
<dd><a href="https://fedoraproject.org/wiki/Legal:Main#Legal">Legal</a></dd>
</dl>
<ul class="list-inline">
<li>
<a href="https:https://www.facebook.com/TheFedoraProject" class="btn-social btn-outline"><i class="fa fa-fw fa-facebook"></i></a>
</li>
<li>
<a href="https:https://plus.google.com/112917221531140868607" class="btn-social btn-outline"><i class="fa fa-fw fa-google-plus"></i></a>
</li>
<li>
<a href="https:https://twitter.com/fedora" class="btn-social btn-outline"><i class="fa fa-fw fa-twitter"></i></a>
</li>
</ul>
</div>
</div>
<div class="col-sm-3 col-xs-6 widget">
<h3 class="widget-title uppercase">Download</h3>
<div class="widget-body">
<dl>
<dd><a href="https://getfedora.org/en/workstation/download">Get Fedora Workstation</a></dd>
<dd><a href="https://getfedora.org/en/server/download">Get Fedora Server</a></dd>
<dd><a href="https://getfedora.org/en/atomic/download">Get Fedora Atomic</a></dd>
<dd><a href="https://spins.fedoraproject.org">Fedora Spins</a></dd>
<dd><a href="https://labs.fedoraproject.org">Fedora Labs</a></dd>
<dd><a href="https://arm.fedoraproject.org">Fedora ARM<span class="sup">&reg;</span></a></dd>
<dd><a href="https://alt.fedoraproject.org/">Alternative Downloads</a></dd>
</dl>
</div>
</div>
<div class="col-sm-3 col-xs-6 widget">
<h3 class="widget-title">Support</h3>
<div class="widget-body">
<dl>
<dd><a href="https://fedoraproject.org/wiki/Communicating_and_getting_help">Get Help</a></dd>
<dd><a href="https://ask.fedoraproject.org/">Ask Fedora</a></dd>
<dd><a href="https://fedoraproject.org/wiki/Common_F27_bugs">Common Bugs</a></dd>
<dd><a href="https://developer.fedoraproject.org/">Fedora Developer Portal</a></dd>
<dd><a href="https://docs.fedoraproject.org/f27/install-guide/index.html">Installation Guide</a></dd>
</dl>
</div>
</div>
<div class="col-sm-3 col-xs-6 widget">
<h3 class="widget-title">Join</h3>
<div class="widget-body">
<dl>
<dd><a href="https://fedoraproject.org/wiki/Join">Join Fedora</a></dd>
<dd><a href="http://fedoraplanet.org">Planet Fedora</a></dd>
<dd><a href="https://fedoraproject.org/wiki/SIGs">Fedora SIGs</a></dd>
<dd><a href="https://admin.fedoraproject.org/accounts/">Fedora Account System</a></dd>
<dd><a href="https://fedoracommunity.org/">Fedora Community</a></dd>
</dl>
</div>
</div>
</div> <!-- /row of widgets -->
<div class="row">
<div class="col-md-2">
<div class="widget-body">
<a href="https://www.redhat.com/"><img class="rh-logo" src="_images/redhat-logo.png" alt="Red Hat Logo" /></a>
</div>
</div>
<div class="col-md-7">
<div class="widget-body">
<p class="sponsor">Fedora is sponsored by Red Hat.</p>
<p class="sponsor"><a href="https://www.redhat.com/en/technologies/linux-platforms/articles/relationship-between-fedora-and-rhel">Learn more about the relationship between Red Hat and Fedora &raquo;</a></p>
<p class="copy">&copy; 2017 Red Hat, Inc. and others. Please send any comments or corrections to the <a href="https://pagure.io/fedora-docs/docs-fp-o">documentation team</a></p>
</div>
</div>
</div> <!-- /row of widgets -->
</div>
</div>
</div>
<!-- jQuery (necessary for Bootstrap's JavaScript plugins) -->
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>
<!-- Include all compiled plugins (below), or include individual files as needed -->
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/js/bootstrap.min.js"></script>
</body>
</html>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.5 KiB

View file

@ -1,61 +0,0 @@
<?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>

Before

Width:  |  Height:  |  Size: 7.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.9 KiB

View file

View file

@ -1,6 +0,0 @@
$(document).ready(function () {
$('[data-toggle="offcanvas"]').click(function () {
$('.sidebar').show();
$('.row-offcanvas').toggleClass('active');
});
});

View file

@ -1,135 +0,0 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<!-- The above 3 meta tags *must* come first in the head; any other head content must come *after* these tags -->
<title>Fedora Documentation Website</title>
<!-- Bootstrap -->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css">
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap-theme.min.css">
<link rel="stylesheet" href="https://overpass-30e2.kxcdn.com/overpass.css">
<link rel="stylesheet" href="_stylesheets/asciibinder.css">
<!-- HTML5 shim and Respond.js for IE8 support of HTML5 elements and media queries -->
<!-- WARNING: Respond.js doesn't work if you view the page via file:// -->
<!--[if lt IE 9]>
<script src="https://oss.maxcdn.com/html5shiv/3.7.2/html5shiv.min.js"></script>
<script src="https://oss.maxcdn.com/respond/1.4.2/respond.min.js"></script>
<![endif]-->
</head>
<body>
<div class="container">
<div class="row">
<div class="page-header">
<img src="/_images/fedora.svg" class="img-responsive" />
<h2><strong>Fedora Documentation Site</strong></h2>
</div>
</div>
<div class="row">
<div class="col-md-8">
<h4><strong>Fedora Documentation - 404 Page Not Found :(</strong></h4>
<p>Hi! You've arrived at Fedora documentation page which does not actually exist. This may be because you followed a link to an older document which has been retired. For reference, you can find those in our <a href="https://docs-old.fedoraproject.org/">old document archive</a>. Or, you can browse <a href="https://docs.fedoraproject.org/">current docs</a>.</p>
<p>It may also be that this page _should_ exist, but sadly does not. If this is the case, and you know what it should say, you can <a href="https://pagure.io/fedora-docs">contribute via the Docs Project</a>.</p>
</div>
</div>
</div>
</div>
<div id="bottom" class="text-muted py-3" >
<div class="foot">
<div class="container">
<div class="row footerlinks">
<div class="col-sm-3 col-xs-6 widget">
<h3 class="widget-title">About</h3>
<div class="widget-body">
<dl>
<dd><a href="https://fedoraproject.org/wiki/Overview">About Fedora</a></dd>
<dd><a href="https://getfedora.org/en/sponsors">Sponsors</a></dd>
<dd><a href="https://fedoramagazine.org">Fedora Magazine</a></dd>
<dd><a href="https://fedoraproject.org/wiki/Legal:Main#Legal">Legal</a></dd>
</dl>
<ul class="list-inline">
<li>
<a href="https:https://www.facebook.com/TheFedoraProject" class="btn-social btn-outline"><i class="fa fa-fw fa-facebook"></i></a>
</li>
<li>
<a href="https:https://plus.google.com/112917221531140868607" class="btn-social btn-outline"><i class="fa fa-fw fa-google-plus"></i></a>
</li>
<li>
<a href="https:https://twitter.com/fedora" class="btn-social btn-outline"><i class="fa fa-fw fa-twitter"></i></a>
</li>
</ul>
</div>
</div>
<div class="col-sm-3 col-xs-6 widget">
<h3 class="widget-title uppercase">Download</h3>
<div class="widget-body">
<dl>
<dd><a href="https://getfedora.org/en/workstation/download">Get Fedora Workstation</a></dd>
<dd><a href="https://getfedora.org/en/server/download">Get Fedora Server</a></dd>
<dd><a href="https://getfedora.org/en/atomic/download">Get Fedora Atomic</a></dd>
<dd><a href="https://spins.fedoraproject.org">Fedora Spins</a></dd>
<dd><a href="https://labs.fedoraproject.org">Fedora Labs</a></dd>
<dd><a href="https://arm.fedoraproject.org">Fedora ARM<span class="sup">&reg;</span></a></dd>
<dd><a href="https://alt.fedoraproject.org/">Alternative Downloads</a></dd>
</dl>
</div>
</div>
<div class="col-sm-3 col-xs-6 widget">
<h3 class="widget-title">Support</h3>
<div class="widget-body">
<dl>
<dd><a href="https://fedoraproject.org/wiki/Communicating_and_getting_help">Get Help</a></dd>
<dd><a href="https://ask.fedoraproject.org/">Ask Fedora</a></dd>
<dd><a href="https://fedoraproject.org/wiki/Common_F27_bugs">Common Bugs</a></dd>
<dd><a href="https://developer.fedoraproject.org/">Fedora Developer Portal</a></dd>
<dd><a href="https://docs.fedoraproject.org/f27/install-guide/index.html">Installation Guide</a></dd>
</dl>
</div>
</div>
<div class="col-sm-3 col-xs-6 widget">
<h3 class="widget-title">Join</h3>
<div class="widget-body">
<dl>
<dd><a href="https://fedoraproject.org/wiki/Join">Join Fedora</a></dd>
<dd><a href="http://fedoraplanet.org">Planet Fedora</a></dd>
<dd><a href="https://fedoraproject.org/wiki/SIGs">Fedora SIGs</a></dd>
<dd><a href="https://admin.fedoraproject.org/accounts/">Fedora Account System</a></dd>
<dd><a href="https://fedoracommunity.org/">Fedora Community</a></dd>
</dl>
</div>
</div>
</div> <!-- /row of widgets -->
<div class="row">
<div class="col-md-2">
<div class="widget-body">
<a href="https://www.redhat.com/"><img class="rh-logo" src="_images/redhat-logo.png" alt="Red Hat Logo" /></a>
</div>
</div>
<div class="col-md-7">
<div class="widget-body">
<p class="sponsor">Fedora is sponsored by Red Hat.</p>
<p class="sponsor"><a href="https://www.redhat.com/en/technologies/linux-platforms/articles/relationship-between-fedora-and-rhel">Learn more about the relationship between Red Hat and Fedora &raquo;</a></p>
<p class="copy">&copy; 2017 Red Hat, Inc. and others. Please send any comments or corrections to the <a href="https://pagure.io/fedora-docs/docs-fp-o">documentation team</a></p>
</div>
</div>
</div> <!-- /row of widgets -->
</div>
</div>
</div>
<!-- jQuery (necessary for Bootstrap's JavaScript plugins) -->
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>
<!-- Include all compiled plugins (below), or include individual files as needed -->
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/js/bootstrap.min.js"></script>
</body>
</html>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.5 KiB

View file

@ -1,61 +0,0 @@
<?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>

Before

Width:  |  Height:  |  Size: 7.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.9 KiB

View file

@ -1,598 +0,0 @@
@import url(https://maxcdn.bootstrapcdn.com/font-awesome/4.1.0/css/font-awesome.min.css);
/* ------------------------------------------------------------
Image: "Spin" https://www.flickr.com/photos/eflon/3655695161/
Author: eflon https://www.flickr.com/photos/eflon/
License: https://creativecommons.org/licenses/by/2.0/
---------------------------------------------------------------*/
.attribution {
text-align: center;
position: relative;
bottom: -20px;
}
.attribution .btn {
color: #808080;
color: rgba(175,175,175, .65);
font-size: 11px;
}
.attribution .btn:hover {
text-decoration: none;
color: #aaa;
}
.popover-content {
font-size: 12px;
line-height: 1.3;
font-weight: normal;
}
@media screen and (max-width: 980px) {
body {
margin-bottom: 200px;
}
footer {
text-align: center;
}
footer .text-right {
text-align: center !important;
}
#footer_social .first {
margin-left: 0;
}
#footer_social > a {
top: 24px;
}
}
.fa-inverse:hover {
color: #ccc;
}
.collapse a.active {
background-color: #DEEAF4;
color: #000;
position: relative;
}
.collapse a.active:hover {
text-decoration: none;
}
.collapse a.active:before {
background-color: #A0C3E5;
content: "";
display: inline-block;
height: 100%;
left: 0;
position: absolute;
top: 0;
width: 3px;
}
.main h2, .main .h2 {
border-top: 0px;
padding-top: 10px;
font-size: 28px;
}
.page-header {
height: 100% !important;
}
.page-header .img-responsive {
display: inline;
}
.page-header h2 {
font-size: 32px;
display: inline;
vertical-align: bottom;
}
.navbar-brand {
padding: initial;
height: initial;
padding: 12px;
}
.navbar-header h2 {
display: inline;
position: absolute;
font-weight: bold;
margin-top: 50px ;
}
.nav > li > a.hover{
background-color: none;
}
h1, h2, h3, h4, h5, h6, .h1, .h2, .h3, .h4, .h5, .h6 {
position: relative;
}
h2 > a.anchor, h3 > a.anchor, h4 > a.anchor, h5 > a.anchor, h6 > a.anchor {
display: block;
font-weight: normal;
margin-left: -1.5ex;
position: absolute;
text-align: center;
text-decoration: none !important;
visibility: hidden;
width: 1.5ex;
z-index: 1001;
}
h2 > a.anchor:before, h3 > a.anchor:before, h4 > a.anchor:before, h5 > a.anchor:before, h6 > a.anchor:before {
content: "\f0c1";
display: block;
font-family: FontAwesome;
font-size: 0.7em;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
padding-top: 0.2em;
}
h4 > a.anchor:before, h5 > a.anchor:before, h6 > a.anchor:before {
font-size: 1em;
}
h2:hover > a.anchor,
h2 > a.anchor:hover,
h3:hover > a.anchor,
h3 > a.anchor:hover,
h4:hover > a.anchor,
h4 > a.anchor:hover,
h5:hover > a.anchor,
h5 > a.anchor:hover,
h6:hover > a.anchor,
h6 > a.anchor:hover {
visibility: visible;
}
.main {
border-left: 1px solid #e7e7e7;
margin-left: -1px;
padding-left: 25px;
}
@media (min-width: 768px) {
.main {
padding-left: 30px;
}
}
/*
* Sidebar
*/
.nav-header {
font-size: 16px;
}
.nav-header ul {
font-size: 14px;
}
.nav-header ul li a {
display: block;
padding: 5px 20px 5px 25px;
font-size: 13px;
font-weight: normal;
}
.nav-sidebar .fa {
text-align: center;
top: -1px;
width: 14px;
}
.nav-sidebar li a {
color: inherit;
}
.nav-sidebar li a:hover {
color: #000;
}
.nav-sidebar ul li ul.nav-tertiary li a {
padding-left: 50px;
}
.nav-sidebar > li > a {
padding: 7px 0;
}
.nav-sidebar > li > a:focus, .nav-sidebar > li > a:hover {
background: transparent;
}
.sidebar {
font-weight: 300;
display: none;
padding-top: 13px;
}
@media screen and (max-width: 767px) {
.sidebar {
padding-left: 30px;
padding-right: 0;
}
}
@media screen and (min-width: 768px) {
.sidebar {
border-right: 1px solid #e7e7e7;
display: block;
}
}
/*
* Off Canvas
* --------------------------------------------------
*/
body, html {
overflow-x: hidden; /* Prevent scroll on narrow devices */
font-family: "Overpass", sans-serif;
}
.toggle-nav {
margin-right: 20px;
}
@media screen and (max-width: 767px) {
.row-offcanvas {
position: relative;
-webkit-transition: all .25s ease-out;
-o-transition: all .25s ease-out;
transition: all .25s ease-out;
}
.row-offcanvas-right {
right: 0;
}
.row-offcanvas-left {
left: 0;
}
.row-offcanvas-right
.sidebar-offcanvas {
right: -75%; /* 8 columns */
}
.row-offcanvas-left
.sidebar-offcanvas {
left: -75%; /* 8 columns */
}
.row-offcanvas-right.active {
right: 75%; /* 8 columns */
}
.row-offcanvas-left.active {
left: 75%; /* 8 columns */
}
.sidebar-offcanvas {
overflow: hidden;
position: absolute;
top: 0;
width: 75%; /* 8 columns */
}
}
p {
margin: 0 0 1.6em;
}
/* Remnants of Asciidoctor default stylesheet - remove styles as needed */
#map_canvas img, #map_canvas embed, #map_canvas object, .map_canvas img, .map_canvas embed, .map_canvas object { max-width: none !important; }
.left { float: left !important; }
.right { float: right !important; }
.text-left { text-align: left !important; }
.text-right { text-align: right !important; }
.text-center { text-align: center !important; }
.text-justify { text-align: justify !important; }
.hide { display: none; }
.subheader, #content #toctitle, .admonitionblock td.content > .title, .audioblock > .title, .exampleblock > .title, .imageblock > .title, .listingblock > .title, .literalblock > .title, .stemblock > .title, .openblock > .title, .paragraph > .title, .quoteblock > .title, table.tableblock > .title, .verseblock > .title, .videoblock > .title, .dlist > .title, .olist > .title, .ulist > .title, .qlist > .title, .hdlist > .title { line-height: 1.4; color: #7a2518; font-weight: 300; margin-top: 0.2em; margin-bottom: 0.5em; }
abbr, acronym { text-transform: uppercase; font-size: 90%; color: #333333; border-bottom: 1px dotted #dddddd; cursor: help; }
abbr { text-transform: none; }
blockquote { margin: 0 0 1.25em; padding: 0.5625em 1.25em 0 1.1875em; border-left: 3px solid #487c58; }
blockquote cite { display: block; font-size: inherit; color: #454545; }
blockquote cite:before { content: "\2014 \0020"; }
blockquote cite a, blockquote cite a:visited { color: #454545; }
blockquote, blockquote p { line-height: 1.6; color: #6e6e6e; }
@media only screen and (min-width: 768px) {
#toctitle, .sidebarblock > .content > .title { line-height: 1.4; }
#toctitle, .sidebarblock > .content > .title { font-size: 1.6875em; }
}
table { background: white; margin-bottom: 1.25em; border: solid 1px #dddddd; }
table thead, table tfoot { background: whitesmoke; font-weight: bold; }
table thead tr th, table thead tr td, table tfoot tr th, table tfoot tr td { padding: 0.5em 0.625em 0.625em; font-size: inherit; color: #333333; text-align: left; }
table tr th, table tr td { padding: 0.5625em 0.625em; font-size: inherit; color: #333333; }
table tr.even, table tr.alt, table tr:nth-of-type(even) { background: #f9f9f9; }
table thead tr th, table tfoot tr th, table tbody tr td, table tr td, table tfoot tr td { display: table-cell; line-height: 1.6; }
.clearfix:before, .clearfix:after, .float-group:before, .float-group:after { content: " "; display: table; }
.clearfix:after, .float-group:after { clear: both; }
*:not(pre) > code { font-size: inherit; padding: 0; white-space: nowrap; background-color: inherit; border: 0 solid #dddddd; -webkit-border-radius: 4px; border-radius: 4px; text-shadow: none; line-height: 1; }
.keyseq { color: #666666; }
kbd:not(.keyseq) { display: inline-block; color: #333333; font-size: 0.75em; line-height: 1.4; background-color: #f7f7f7; border: 1px solid #ccc; -webkit-border-radius: 3px; border-radius: 3px; -webkit-box-shadow: 0 1px 0 rgba(0, 0, 0, 0.2), 0 0 0 2px white inset; box-shadow: 0 1px 0 rgba(0, 0, 0, 0.2), 0 0 0 2px white inset; margin: -0.15em 0.15em 0 0.15em; padding: 0.2em 0.6em 0.2em 0.5em; vertical-align: middle; white-space: nowrap; }
.keyseq kbd:first-child { margin-left: 0; }
.keyseq kbd:last-child { margin-right: 0; }
.menuseq, .menu { color: #1a1a1a; }
b.button:before, b.button:after { position: relative; top: -1px; font-weight: normal; }
b.button:before { content: "["; padding: 0 3px 0 2px; }
b.button:after { content: "]"; padding: 0 2px 0 3px; }
p a > code:hover { color: #561309; }
#header, #content, #footnotes, #footer { width: 100%; margin-left: auto; margin-right: auto; margin-top: 0; margin-bottom: 0; max-width: 62.5em; *zoom: 1; position: relative; padding-left: 0.9375em; padding-right: 0.9375em; }
#header:before, #header:after, #content:before, #content:after, #footnotes:before, #footnotes:after, #footer:before, #footer:after { content: " "; display: table; }
#header:after, #content:after, #footnotes:after, #footer:after { clear: both; }
#content:before { content: none; }
#header { margin-bottom: 2.5em; }
#header > h1 { color: black; font-weight: 300; border-bottom: 1px solid #d8d8d8; margin-bottom: -28px; padding-bottom: 32px; }
#header span { color: #6e6e6e; }
#header #revnumber { text-transform: capitalize; }
#header br { display: none; }
#header br + span { padding-left: 3px; }
#header br + span:before { content: "\2013 \0020"; }
#header br + span.author { padding-left: 0; }
#header br + span.author:before { content: ", "; }
#toc { border-bottom: 3px double #e5e5e5; padding-top: 1em; padding-bottom: 1.25em; }
#toc > ul { margin-left: 0.25em; }
#toc ul.sectlevel0 > li > a { font-style: italic; }
#toc ul.sectlevel0 ul.sectlevel1 { margin-left: 0; margin-top: 0.5em; margin-bottom: 0.5em; }
#toc ul { font-family: "Open Sans", "DejaVu Sans", "Sans", sans-serif; list-style-type: none; }
#toc a { text-decoration: none; }
#toc a:active { text-decoration: underline; }
#toctitle { color: #7a2518; }
@media only screen and (min-width: 768px) { body.toc2 { padding-left: 15em; padding-right: 0; }
#toc.toc2 { background-color: #fafaf9; position: fixed; width: 15em; left: 0; top: 0; border-right: 1px solid #e5e5e5; border-bottom: 0; z-index: 1000; padding: 1.25em 1em; height: 100%; overflow: auto; }
#toc.toc2 #toctitle { margin-top: 0; font-size: 1.2em; }
#toc.toc2 > ul { font-size: .90em; margin-bottom: 0; }
#toc.toc2 ul ul { margin-left: 0; padding-left: 1em; }
#toc.toc2 ul.sectlevel0 ul.sectlevel1 { padding-left: 0; margin-top: 0.5em; margin-bottom: 0.5em; }
body.toc2.toc-right { padding-left: 0; padding-right: 15em; }
body.toc2.toc-right #toc.toc2 { border-right: 0; border-left: 1px solid #e5e5e5; left: auto; right: 0; } }
@media only screen and (min-width: 1280px) { body.toc2 { padding-left: 20em; padding-right: 0; }
#toc.toc2 { width: 20em; }
#toc.toc2 #toctitle { font-size: 1.375em; }
#toc.toc2 > ul { font-size: 0.95em; }
#toc.toc2 ul ul { padding-left: 1.25em; }
body.toc2.toc-right { padding-left: 0; padding-right: 20em; } }
#content #toc { border-style: solid; border-width: 1px; border-color: #e3e3dd; margin-bottom: 1.25em; padding: 1.25em; background: #fafaf9; border-width: 0; -webkit-border-radius: 4px; border-radius: 4px; }
#content #toc > :first-child { margin-top: 0; }
#content #toc > :last-child { margin-bottom: 0; }
#content #toctitle { font-size: 1.375em; }
#footer { max-width: 100%; background-color: #333333; padding: 1.25em; }
#footer-text { color: #cccccc; line-height: 1.44; }
.audioblock, .imageblock, .literalblock, .listingblock, .stemblock, .verseblock, .videoblock { margin-bottom: 2.5em; }
.admonitionblock td.content > .title, .audioblock > .title, .exampleblock > .title, .imageblock > .title, .listingblock > .title, .literalblock > .title, .stemblock > .title, .openblock > .title, .paragraph > .title, .quoteblock > .title, table.tableblock > .title, .verseblock > .title, .videoblock > .title, .dlist > .title, .olist > .title, .ulist > .title, .qlist > .title, .hdlist > .title { text-rendering: optimizeLegibility; text-align: left; font-family: "Noto Serif", "DejaVu Serif", "Serif", serif; font-weight: normal; font-style: italic; }
table.tableblock > caption.title { white-space: nowrap; overflow: visible; max-width: 0; }
table.tableblock #preamble > .sectionbody > .paragraph:first-of-type p { font-size: inherit; }
.admonitionblock > table { border: 0; background: none; width: 100%; }
.admonitionblock > table td.icon { text-align: center; width: 80px; }
.admonitionblock > table td.icon img { max-width: none; }
.admonitionblock > table td.icon .title { font-weight: 300; text-transform: uppercase; }
.admonitionblock > table td.content { padding-left: 0; padding-right: 1.25em; color: #6e6e6e; }
.admonitionblock > table td.content > :last-child > :last-child { margin-bottom: 0; }
.exampleblock > .content { border-style: solid; border-width: 1px; border-color: #e6e6e6; margin-bottom: 1.25em; padding: 1.25em; background: white; -webkit-border-radius: 4px; border-radius: 4px; }
.exampleblock > .content > :first-child { margin-top: 0; }
.exampleblock > .content > :last-child { margin-bottom: 0; }
.exampleblock > .content h1, .exampleblock > .content h2, .exampleblock > .content h3, .exampleblock > .content #toctitle, .sidebarblock.exampleblock > .content > .title, .exampleblock > .content h4, .exampleblock > .content h5, .exampleblock > .content h6, .exampleblock > .content p { color: #333333; }
.exampleblock > .content h1, .exampleblock > .content h2, .exampleblock > .content h3, .exampleblock > .content #toctitle, .sidebarblock.exampleblock > .content > .title, .exampleblock > .content h4, .exampleblock > .content h5, .exampleblock > .content h6 { line-height: 1; margin-bottom: 0.625em; }
.exampleblock > .content h1.subheader, .exampleblock > .content h2.subheader, .exampleblock > .content h3.subheader, .exampleblock > .content .subheader#toctitle, .sidebarblock.exampleblock > .content > .subheader.title, .exampleblock > .content h4.subheader, .exampleblock > .content h5.subheader, .exampleblock > .content h6.subheader { line-height: 1.4; }
.exampleblock.result > .content { -webkit-box-shadow: 0 1px 8px #e3e3dd; box-shadow: 0 1px 8px #e3e3dd; }
.sidebarblock { border-style: solid; border-width: 1px; border-color: #e3e3dd; margin-top: -1.0em; margin-bottom: 1.6em; margin-left: 1em; padding: .5em; background: #F1F3F5; -webkit-border-radius: 4px; border-radius: 4px; overflow-x: auto; float: right; width: 40%; }
.sidebarblock > :first-child { margin-top: 0; }
.sidebarblock > :last-child { margin-bottom: 0; }
.sidebarblock h1, .sidebarblock h2, .sidebarblock h3, .sidebarblock #toctitle, .sidebarblock > .content > .title, .sidebarblock h4, .sidebarblock h5, .sidebarblock h6, .sidebarblock p { color: #333333; }
.sidebarblock h1, .sidebarblock h2, .sidebarblock h3, .sidebarblock #toctitle, .sidebarblock > .content > .title, .sidebarblock h4, .sidebarblock h5, .sidebarblock h6 { line-height: 1; margin-bottom: 0.625em; }
.sidebarblock h1.subheader, .sidebarblock h2.subheader, .sidebarblock h3.subheader, .sidebarblock .subheader#toctitle, .sidebarblock > .content > .subheader.title, .sidebarblock h4.subheader, .sidebarblock h5.subheader, .sidebarblock h6.subheader { line-height: 1.4; }
.sidebarblock > .content > .title { color: inherit; font-size: 28px; font-weight: 500; margin-top: 0; line-height: 1.6; }
.width50 { width: 50% ! important}
.exampleblock > .content > :last-child > :last-child, .exampleblock > .content .olist > ol > li:last-child > :last-child, .exampleblock > .content .ulist > ul > li:last-child > :last-child, .exampleblock > .content .qlist > ol > li:last-child > :last-child, .sidebarblock > .content > :last-child > :last-child, .sidebarblock > .content .olist > ol > li:last-child > :last-child, .sidebarblock > .content .ulist > ul > li:last-child > :last-child, .sidebarblock > .content .qlist > ol > li:last-child > :last-child { margin-bottom: 0; }
.literalblock pre, .literalblock pre[class], .listingblock pre, .listingblock pre[class] { border: 0px; background-color: #F0F3F5; -webkit-border-radius: 5px; border-radius: 5px; padding: 1.5em 2.5em; word-wrap: break-word; }
.literalblock pre.nowrap, .literalblock pre[class].nowrap, .listingblock pre.nowrap, .listingblock pre[class].nowrap { overflow-x: auto; white-space: pre; word-wrap: normal; }
.literalblock pre > code, .literalblock pre[class] > code, .listingblock pre > code, .listingblock pre[class] > code { display: block; }
.listingblock > .content { position: relative; }
.listingblock:hover code[class*=" language-"]:before { text-transform: uppercase; font-size: 0.9em; color: #999; position: absolute; top: 0.375em; right: 0.375em; }
.listingblock:hover code.asciidoc:before { content: "asciidoc"; }
.listingblock:hover code.clojure:before { content: "clojure"; }
.listingblock:hover code.css:before { content: "css"; }
.listingblock:hover code.go:before { content: "go"; }
.listingblock:hover code.groovy:before { content: "groovy"; }
.listingblock:hover code.html:before { content: "html"; }
.listingblock:hover code.java:before { content: "java"; }
.listingblock:hover code.javascript:before { content: "javascript"; }
.listingblock:hover code.python:before { content: "python"; }
.listingblock:hover code.ruby:before { content: "ruby"; }
.listingblock:hover code.sass:before { content: "sass"; }
.listingblock:hover code.scss:before { content: "scss"; }
.listingblock:hover code.xml:before { content: "xml"; }
.listingblock:hover code.yaml:before { content: "yaml"; }
.listingblock.terminal pre .command:before { content: attr(data-prompt); padding-right: 0.5em; color: #999; }
.listingblock.terminal pre .command:not([data-prompt]):before { content: '$'; }
table.pyhltable { border: 0; margin-bottom: 0; }
table.pyhltable td { vertical-align: top; padding-top: 0; padding-bottom: 0; }
table.pyhltable td.code { padding-left: .75em; padding-right: 0; }
.highlight.pygments .lineno, table.pyhltable td:not(.code) { color: #999; padding-left: 0; padding-right: .5em; border-right: 1px solid #d8d8d8; }
.highlight.pygments .lineno { display: inline-block; margin-right: .25em; }
table.pyhltable .linenodiv { background-color: transparent !important; padding-right: 0 !important; }
.quoteblock { margin: 0 0 1.25em 0; padding: 0.5625em 1.25em 0 1.1875em; border-left: 3px solid #487c58; }
.quoteblock blockquote { margin: 0 0 1.25em 0; padding: 0 0 0.625em 0; border: 0; }
.quoteblock blockquote > .paragraph:last-child p { margin-bottom: 0; }
.quoteblock .attribution { margin-top: -0.625em; padding-bottom: 0.625em; font-size: inherit; color: #454545; line-height: 1.6; }
.quoteblock .attribution br { display: none; }
.quoteblock .attribution cite { display: block; }
table.tableblock { max-width: 100%; }
table.tableblock td .paragraph:last-child p > p:last-child, table.tableblock th > p:last-child, table.tableblock td > p:last-child { margin-bottom: 0; }
table.spread { width: 100%; }
table.tableblock, th.tableblock, td.tableblock { border: 0 solid #dddddd; }
table.grid-all th.tableblock, table.grid-all td.tableblock { border-width: 0 1px 1px 0; }
table.grid-all tfoot > tr > th.tableblock, table.grid-all tfoot > tr > td.tableblock { border-width: 1px 1px 0 0; }
table.grid-cols th.tableblock, table.grid-cols td.tableblock { border-width: 0 1px 0 0; }
table.grid-all * > tr > .tableblock:last-child, table.grid-cols * > tr > .tableblock:last-child { border-right-width: 0; }
table.grid-rows th.tableblock, table.grid-rows td.tableblock { border-width: 0 0 1px 0; }
table.grid-all tbody > tr:last-child > th.tableblock, table.grid-all tbody > tr:last-child > td.tableblock, table.grid-all thead:last-child > tr > th.tableblock, table.grid-rows tbody > tr:last-child > th.tableblock, table.grid-rows tbody > tr:last-child > td.tableblock, table.grid-rows thead:last-child > tr > th.tableblock { border-bottom-width: 0; }
table.grid-rows tfoot > tr > th.tableblock, table.grid-rows tfoot > tr > td.tableblock { border-width: 1px 0 0 0; }
table.frame-all { border-width: 1px; }
table.frame-sides { border-width: 0 1px; }
table.frame-topbot { border-width: 1px 0; }
th.halign-left, td.halign-left { text-align: left; }
th.halign-right, td.halign-right { text-align: right; }
th.halign-center, td.halign-center { text-align: center; }
th.valign-top, td.valign-top { vertical-align: top; }
th.valign-bottom, td.valign-bottom { vertical-align: bottom; }
th.valign-middle, td.valign-middle { vertical-align: middle; }
table thead th, table tfoot th { font-weight: bold; }
tbody tr th { display: table-cell; line-height: 1.6; background: whitesmoke; }
tbody tr th, tbody tr th p, tfoot tr th, tfoot tr th p { color: #333333; font-weight: bold; }
td > div.verse { white-space: pre; }
ul.unstyled, ol.unnumbered, ul.checklist, ul.none { list-style-type: none; }
ul.unstyled, ol.unnumbered, ul.checklist { margin-left: 0.625em; }
ul.checklist li > p:first-child > .fa-check-square-o:first-child, ul.checklist li > p:first-child > input[type="checkbox"]:first-child { margin-right: 0.25em; }
ul.checklist li > p:first-child > input[type="checkbox"]:first-child { position: relative; top: 1px; }
ul.inline { margin: 0 auto 0.625em auto; margin-left: -1.375em; margin-right: 0; padding: 0; list-style: none; overflow: hidden; }
ul.inline > li { list-style: none; float: left; margin-left: 1.375em; display: block; }
ul.inline > li > * { display: block; }
.unstyled dl dt { font-weight: normal; font-style: normal; }
ol.arabic { list-style-type: decimal; }
ol.decimal { list-style-type: decimal-leading-zero; }
ol.loweralpha { list-style-type: lower-alpha; }
ol.upperalpha { list-style-type: upper-alpha; }
ol.lowerroman { list-style-type: lower-roman; }
ol.upperroman { list-style-type: upper-roman; }
ol.lowergreek { list-style-type: lower-greek; }
.hdlist > table, .colist > table { border: 0; background: none; }
.hdlist > table > tbody > tr, .colist > table > tbody > tr { background: none; }
td.hdlist1 { padding-right: .75em; font-weight: bold; }
td.hdlist1, td.hdlist2 { vertical-align: top; }
.literalblock + .colist, .listingblock + .colist { margin-top: -0.5em; }
.colist > table tr > td:first-of-type { padding: 0 .75em; line-height: 1; }
.colist > table tr > td:last-of-type { padding: 0.25em 0; }
.qanda > ol > li > p > em:only-child { color: #1d4b8f; }
.thumb, .th { line-height: 0; display: inline-block; border: solid 4px white; -webkit-box-shadow: 0 0 0 1px #dddddd; box-shadow: 0 0 0 1px #dddddd; }
.imageblock.left, .imageblock[style*="float: left"] { margin: 0.25em 0.625em 1.25em 0; }
.imageblock.right, .imageblock[style*="float: right"] { margin: 0.25em 0 1.25em 0.625em; }
.imageblock > .title { margin-bottom: 0; }
.imageblock.thumb, .imageblock.th { border-width: 6px; }
.imageblock.thumb > .title, .imageblock.th > .title { padding: 0 0.125em; }
.image.left, .image.right { margin-top: 0.25em; margin-bottom: 0.25em; display: inline-block; line-height: 0; }
.image.left { margin-right: 0.625em; }
.image.right { margin-left: 0.625em; }
a.image { text-decoration: none; }
span.footnote, span.footnoteref { vertical-align: super; font-size: 0.875em; }
span.footnote a, span.footnoteref a { text-decoration: none; }
span.footnote a:active, span.footnoteref a:active { text-decoration: underline; }
#footnotes { padding-top: 0.75em; padding-bottom: 0.75em; margin-bottom: 0.625em; }
#footnotes hr { width: 20%; min-width: 6.25em; margin: -.25em 0 .75em 0; border-width: 1px 0 0 0; }
#footnotes .footnote { padding: 0 0.375em; line-height: 1.3; font-size: 0.875em; margin-left: 1.2em; text-indent: -1.2em; margin-bottom: .2em; }
#footnotes .footnote a:first-of-type { font-weight: bold; text-decoration: none; }
#footnotes .footnote:last-of-type { margin-bottom: 0; }
#content #footnotes { margin-top: -0.625em; margin-bottom: 0; padding: 0.75em 0; }
.gist .file-data > table { border: none; background: #fff; width: 100%; margin-bottom: 0; }
.gist .file-data > table td.line-data { width: 99%; }
div.unbreakable { page-break-inside: avoid; }
.replaceable { font-style: italic; font-color: inherit; font-family: inherit; }
.parameter { font-style: italic; font-family: monospace; }
.userinput { font-weight: bold; font-family: monospace; }
.envar { font-weight: bold; font-family: monospace; font-size: 90%; }
.sysitem { font-weight: bold; font-size: 90%; }
.package { font-weight: bold; font-size: 90%; }
.filename { font-weight: bold; font-style: italic; font-size: 90%; }
.big { font-size: larger; }
.small { font-size: smaller; }
.underline { text-decoration: underline; }
.overline { text-decoration: overline; }
.line-through { text-decoration: line-through; }
.aqua { color: #00bfbf; }
.aqua-background { background-color: #00fafa; }
.black { color: black; }
.black-background { background-color: black; }
.blue { color: #0000bf; }
.blue-background { background-color: #0000fa; }
.fuchsia { color: #bf00bf; }
.fuchsia-background { background-color: #fa00fa; }
.gray { color: #606060; }
.gray-background { background-color: #7d7d7d; }
.green { color: #006000; }
.green-background { background-color: #007d00; }
.lime { color: #00bf00; }
.lime-background { background-color: #00fa00; }
.maroon { color: #600000; }
.maroon-background { background-color: #7d0000; }
.navy { color: #000060; }
.navy-background { background-color: #00007d; }
.olive { color: #606000; }
.olive-background { background-color: #7d7d00; }
.purple { color: #600060; }
.purple-background { background-color: #7d007d; }
.red { color: #bf0000; }
.red-background { background-color: #fa0000; }
.silver { color: #909090; }
.silver-background { background-color: #bcbcbc; }
.teal { color: #006060; }
.teal-background { background-color: #007d7d; }
.white { color: #bfbfbf; }
.white-background { background-color: #fafafa; }
.yellow { color: #bfbf00; }
.yellow-background { background-color: #fafa00; }
span.icon > .fa { cursor: default; }
.admonitionblock td.icon [class^="fa icon-"] { font-size: 2.5em; cursor: default; }
.admonitionblock td.icon .icon-note:before { content: "\f05a"; color: #4E9FDD; }
.admonitionblock td.icon .icon-tip:before { content: "\f0eb"; color: #2C8596; }
.admonitionblock td.icon .icon-warning:before { content: "\f071"; color: #ec7a08; }
.admonitionblock td.icon .icon-caution:before { content: "\f06d"; color: #ec7a08; }
.admonitionblock td.icon .icon-important:before { content: "\f06a"; color: #c00; }
.conum[data-value] { display: inline-block; color: white !important; background-color: #333333; -webkit-border-radius: 100px; border-radius: 100px; text-align: center; width: 20px; height: 20px; font-size: 12px; line-height: 20px; font-family: "Open Sans", "Sans", sans-serif; font-style: normal; font-weight: bold; text-indent: -1px; }
.conum[data-value] * { color: white !important; }
.conum[data-value] + b { display: none; }
.conum[data-value]:after { content: attr(data-value); }
pre .conum[data-value] { position: relative; top: -2px; }
b.conum * { color: inherit !important; }
.conum:not([data-value]):empty { display: none; }
.print-only { display: none !important; }
@media print { @page { margin: 1.25cm 0.75cm; }
* { -webkit-box-shadow: none !important; box-shadow: none !important; text-shadow: none !important; }
a, a:visited { color: inherit !important; text-decoration: underline !important; }
a[href^="http:"]:after, a[href^="https:"]:after { content: " (" attr(href) ")"; }
a[href^="#"], a[href^="#"]:visited, a[href^="mailto:"], a[href^="mailto:"]:visited { text-decoration: none !important; }
abbr[title]:after { content: " (" attr(title) ")"; }
pre, blockquote { page-break-inside: avoid; }
code { color: #191919; }
thead { display: table-header-group; }
tr, img { page-break-inside: avoid; }
img { max-width: 100% !important; }
p { orphans: 3; widows: 3; }
h2, h3, #toctitle, .sidebarblock > .content > .title, #toctitle, .sidebarblock > .content > .title { page-break-after: avoid; }
#toc, .sidebarblock { background: none !important; }
#toc { border-bottom: 1px solid #d8d8d8 !important; padding-bottom: 0 !important; }
.sect1 { padding-bottom: 0 !important; }
.sect1 + .sect1 { border: none !important; }
body.book #header { text-align: center; }
body.book #header > h1 { border: none !important; margin: 2.5em 0 1em 0; padding: 0; }
body.book #header span { line-height: 1.6; }
body.book #header br { display: block; }
body.book #header br + span { padding-left: 0; }
body.book #header br + span:before { content: none !important; }
body.book #toc { border: none !important; text-align: left !important; padding: 0 !important; }
#footer { background: none !important; }
#footer-text { color: #333333 !important; }
.hide-on-print { display: none !important; }
.print-only { display: block !important; }
.hide-for-print { display: none !important; }
.show-for-print { display: inherit !important; } }
.corner-ribbon{
width: 16em;
background: #3c6eb4 ;
position: absolute;
top: 3em;
right: -4em;
text-align: center;
line-height: 5ex;
color: #dedede;
transform: rotate(45deg);
-webkit-transform: rotate(45deg);
z-index: 999;
}
.corner-ribbon a { color: #FFFFFF; }

View file

@ -1,141 +0,0 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<!-- The above 3 meta tags *must* come first in the head; any other head content must come *after* these tags -->
<title>Fedora Defensive Coding Guide Docs Website</title>
<!-- Bootstrap -->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css">
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap-theme.min.css">
<link rel="stylesheet" href="https://overpass-30e2.kxcdn.com/overpass.css">
<link rel="stylesheet" href="_stylesheets/asciibinder.css">
<!-- HTML5 shim and Respond.js for IE8 support of HTML5 elements and media queries -->
<!-- WARNING: Respond.js doesn't work if you view the page via file:// -->
<!--[if lt IE 9]>
<script src="https://oss.maxcdn.com/html5shiv/3.7.2/html5shiv.min.js"></script>
<script src="https://oss.maxcdn.com/respond/1.4.2/respond.min.js"></script>
<![endif]-->
</head>
<body>
<div class="container">
<div class="row">
<div class="page-header">
<img src="_images/fedora.svg" class="img-responsive" />
</div>
</div>
<div class="row">
<div class="col-md-8">
<h4><strong>Fedora Defensive Coding Guide Docs Site</strong></h4>
<p>Test Build.</p>
</div>
<div class="col-md-4">
<h5><strong>Fedora Defensive Coding Guide Docs</strong></h5>
<div class="list-group">
<a href="master/en-US/index.html" class="list-group-item">
&nbsp;Documentation
</a>
</div>
</div>
</div>
</div>
<div id="bottom" class="text-muted py-3" >
<div class="foot">
<div class="container">
<div class="row footerlinks">
<div class="col-sm-3 col-xs-6 widget">
<h3 class="widget-title">About</h3>
<div class="widget-body">
<dl>
<dd><a href="https://fedoraproject.org/wiki/Overview">About Fedora</a></dd>
<dd><a href="https://getfedora.org/en/sponsors">Sponsors</a></dd>
<dd><a href="https://fedoramagazine.org">Fedora Magazine</a></dd>
<dd><a href="https:https://fedoraproject.org/wiki/Legal:Main#Legal">Legal</a></dd>
</dl>
<ul class="list-inline">
<li>
<a href="https:https://www.facebook.com/TheFedoraProject" class="btn-social btn-outline"><i class="fa fa-fw fa-facebook"></i></a>
</li>
<li>
<a href="https:https://plus.google.com/112917221531140868607" class="btn-social btn-outline"><i class="fa fa-fw fa-google-plus"></i></a>
</li>
<li>
<a href="https:https://twitter.com/fedora" class="btn-social btn-outline"><i class="fa fa-fw fa-twitter"></i></a>
</li>
</ul>
</div>
</div>
<div class="col-sm-3 col-xs-6 widget">
<h3 class="widget-title uppercase">Download</h3>
<div class="widget-body">
<dl>
<dd><a href="https://getfedora.org/en/workstation/download">Get Fedora Workstation</a></dd>
<dd><a href="https://getfedora.org/en/server/download">Get Fedora Server</a></dd>
<dd><a href="https://getfedora.org/en/atomic/download">Get Fedora Atomic</a></dd>
<dd><a href="https://spins.fedoraproject.org">Fedora Spins</a></dd>
<dd><a href="https://labs.fedoraproject.org">Fedora Labs</a></dd>
<dd><a href="https://arm.fedoraproject.org">Fedora ARM<span class="sup">&reg;</span></a></dd>
<dd><a href="https://alt.fedoraproject.org/">Alternative Downloads</a></dd>
</dl>
</div>
</div>
<div class="col-sm-3 col-xs-6 widget">
<h3 class="widget-title">Support</h3>
<div class="widget-body">
<dl>
<dd><a href="https://fedoraproject.org/wiki/Communicating_and_getting_help">Get Help</a></dd>
<dd><a href="https://ask.fedoraproject.org/">Ask Fedora</a></dd>
<dd><a href="https://fedoraproject.org/wiki/Common_F${global_variables.release['curr_id']}_bugs">Common Bugs</a></dd>
<dd><a href="https://developer.fedoraproject.org/">Fedora Developer Portal</a></dd>
<dd><a href="https://docs.fedoraproject.org/en-US/Fedora/${global_variables.release['curr_id']}/html/Installation_Guide">Installation Guide</a></dd>
</dl>
</div>
</div>
<div class="col-sm-3 col-xs-6 widget">
<h3 class="widget-title">Join</h3>
<div class="widget-body">
<dl>
<dd><a href="https://fedoraproject.org/wiki/Join">Join Fedora</a></dd>
<dd><a href="http://fedoraplanet.org">Planet Fedora</a></dd>
<dd><a href="https://fedoraproject.org/wiki/SIGs">Fedora SIGs</a></dd>
<dd><a href="https://admin.fedoraproject.org/accounts/">Fedora Account System</a></dd>
<dd><a href="https://fedoracommunity.org/">Fedora Community</a></dd>
</dl>
</div>
</div>
</div> <!-- /row of widgets -->
<div class="row">
<div class="col-md-2">
<div class="widget-body">
<a href="https://www.redhat.com/"><img class="rh-logo" src="_images/redhat-logo.png" alt="Red Hat Logo" /></a>
</div>
</div>
<div class="col-md-7">
<div class="widget-body">
<p class="sponsor">Fedora is sponsored by Red Hat.</p>
<p class="sponsor"><a href="https://www.redhat.com/en/technologies/linux-platforms/articles/relationship-between-fedora-and-rhel">Learn more about the relationship between Red Hat and Fedora &raquo;</a></p>
<p class="copy">&copy; 2017 Red Hat, Inc. and others. Please send any comments or corrections to the <a href="https://fedorahosted.org/fedora-websites/">websites team</a></p>
</div>
</div>
</div> <!-- /row of widgets -->
</div>
</div>
</div>
<!-- jQuery (necessary for Bootstrap's JavaScript plugins) -->
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>
<!-- Include all compiled plugins (below), or include individual files as needed -->
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/js/bootstrap.min.js"></script>
</body>
</html>

View file

@ -1,135 +0,0 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<!-- The above 3 meta tags *must* come first in the head; any other head content must come *after* these tags -->
<title>Fedora Documentation Website</title>
<!-- Bootstrap -->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css">
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap-theme.min.css">
<link rel="stylesheet" href="https://overpass-30e2.kxcdn.com/overpass.css">
<link rel="stylesheet" href="_stylesheets/asciibinder.css">
<!-- HTML5 shim and Respond.js for IE8 support of HTML5 elements and media queries -->
<!-- WARNING: Respond.js doesn't work if you view the page via file:// -->
<!--[if lt IE 9]>
<script src="https://oss.maxcdn.com/html5shiv/3.7.2/html5shiv.min.js"></script>
<script src="https://oss.maxcdn.com/respond/1.4.2/respond.min.js"></script>
<![endif]-->
</head>
<body>
<div class="container">
<div class="row">
<div class="page-header">
<img src="/_images/fedora.svg" class="img-responsive" />
<h2><strong>Fedora Documentation Site</strong></h2>
</div>
</div>
<div class="row">
<div class="col-md-8">
<h4><strong>Fedora Documentation - 404 Page Not Found :(</strong></h4>
<p>Hi! You've arrived at Fedora documentation page which does not actually exist. This may be because you followed a link to an older document which has been retired. For reference, you can find those in our <a href="https://docs-old.fedoraproject.org/">old document archive</a>. Or, you can browse <a href="https://docs.fedoraproject.org/">current docs</a>.</p>
<p>It may also be that this page _should_ exist, but sadly does not. If this is the case, and you know what it should say, you can <a href="https://pagure.io/fedora-docs">contribute via the Docs Project</a>.</p>
</div>
</div>
</div>
</div>
<div id="bottom" class="text-muted py-3" >
<div class="foot">
<div class="container">
<div class="row footerlinks">
<div class="col-sm-3 col-xs-6 widget">
<h3 class="widget-title">About</h3>
<div class="widget-body">
<dl>
<dd><a href="https://fedoraproject.org/wiki/Overview">About Fedora</a></dd>
<dd><a href="https://getfedora.org/en/sponsors">Sponsors</a></dd>
<dd><a href="https://fedoramagazine.org">Fedora Magazine</a></dd>
<dd><a href="https://fedoraproject.org/wiki/Legal:Main#Legal">Legal</a></dd>
</dl>
<ul class="list-inline">
<li>
<a href="https:https://www.facebook.com/TheFedoraProject" class="btn-social btn-outline"><i class="fa fa-fw fa-facebook"></i></a>
</li>
<li>
<a href="https:https://plus.google.com/112917221531140868607" class="btn-social btn-outline"><i class="fa fa-fw fa-google-plus"></i></a>
</li>
<li>
<a href="https:https://twitter.com/fedora" class="btn-social btn-outline"><i class="fa fa-fw fa-twitter"></i></a>
</li>
</ul>
</div>
</div>
<div class="col-sm-3 col-xs-6 widget">
<h3 class="widget-title uppercase">Download</h3>
<div class="widget-body">
<dl>
<dd><a href="https://getfedora.org/en/workstation/download">Get Fedora Workstation</a></dd>
<dd><a href="https://getfedora.org/en/server/download">Get Fedora Server</a></dd>
<dd><a href="https://getfedora.org/en/atomic/download">Get Fedora Atomic</a></dd>
<dd><a href="https://spins.fedoraproject.org">Fedora Spins</a></dd>
<dd><a href="https://labs.fedoraproject.org">Fedora Labs</a></dd>
<dd><a href="https://arm.fedoraproject.org">Fedora ARM<span class="sup">&reg;</span></a></dd>
<dd><a href="https://alt.fedoraproject.org/">Alternative Downloads</a></dd>
</dl>
</div>
</div>
<div class="col-sm-3 col-xs-6 widget">
<h3 class="widget-title">Support</h3>
<div class="widget-body">
<dl>
<dd><a href="https://fedoraproject.org/wiki/Communicating_and_getting_help">Get Help</a></dd>
<dd><a href="https://ask.fedoraproject.org/">Ask Fedora</a></dd>
<dd><a href="https://fedoraproject.org/wiki/Common_F27_bugs">Common Bugs</a></dd>
<dd><a href="https://developer.fedoraproject.org/">Fedora Developer Portal</a></dd>
<dd><a href="https://docs.fedoraproject.org/f27/install-guide/index.html">Installation Guide</a></dd>
</dl>
</div>
</div>
<div class="col-sm-3 col-xs-6 widget">
<h3 class="widget-title">Join</h3>
<div class="widget-body">
<dl>
<dd><a href="https://fedoraproject.org/wiki/Join">Join Fedora</a></dd>
<dd><a href="http://fedoraplanet.org">Planet Fedora</a></dd>
<dd><a href="https://fedoraproject.org/wiki/SIGs">Fedora SIGs</a></dd>
<dd><a href="https://admin.fedoraproject.org/accounts/">Fedora Account System</a></dd>
<dd><a href="https://fedoracommunity.org/">Fedora Community</a></dd>
</dl>
</div>
</div>
</div> <!-- /row of widgets -->
<div class="row">
<div class="col-md-2">
<div class="widget-body">
<a href="https://www.redhat.com/"><img class="rh-logo" src="_images/redhat-logo.png" alt="Red Hat Logo" /></a>
</div>
</div>
<div class="col-md-7">
<div class="widget-body">
<p class="sponsor">Fedora is sponsored by Red Hat.</p>
<p class="sponsor"><a href="https://www.redhat.com/en/technologies/linux-platforms/articles/relationship-between-fedora-and-rhel">Learn more about the relationship between Red Hat and Fedora &raquo;</a></p>
<p class="copy">&copy; 2017 Red Hat, Inc. and others. Please send any comments or corrections to the <a href="https://pagure.io/fedora-docs/docs-fp-o">documentation team</a></p>
</div>
</div>
</div> <!-- /row of widgets -->
</div>
</div>
</div>
<!-- jQuery (necessary for Bootstrap's JavaScript plugins) -->
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>
<!-- Include all compiled plugins (below), or include individual files as needed -->
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/js/bootstrap.min.js"></script>
</body>
</html>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.5 KiB

View file

@ -1,61 +0,0 @@
<?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>

Before

Width:  |  Height:  |  Size: 7.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.9 KiB

View file

@ -1,6 +0,0 @@
$(document).ready(function () {
$('[data-toggle="offcanvas"]').click(function () {
$('.sidebar').show();
$('.row-offcanvas').toggleClass('active');
});
});

View file

@ -1,598 +0,0 @@
@import url(https://maxcdn.bootstrapcdn.com/font-awesome/4.1.0/css/font-awesome.min.css);
/* ------------------------------------------------------------
Image: "Spin" https://www.flickr.com/photos/eflon/3655695161/
Author: eflon https://www.flickr.com/photos/eflon/
License: https://creativecommons.org/licenses/by/2.0/
---------------------------------------------------------------*/
.attribution {
text-align: center;
position: relative;
bottom: -20px;
}
.attribution .btn {
color: #808080;
color: rgba(175,175,175, .65);
font-size: 11px;
}
.attribution .btn:hover {
text-decoration: none;
color: #aaa;
}
.popover-content {
font-size: 12px;
line-height: 1.3;
font-weight: normal;
}
@media screen and (max-width: 980px) {
body {
margin-bottom: 200px;
}
footer {
text-align: center;
}
footer .text-right {
text-align: center !important;
}
#footer_social .first {
margin-left: 0;
}
#footer_social > a {
top: 24px;
}
}
.fa-inverse:hover {
color: #ccc;
}
.collapse a.active {
background-color: #DEEAF4;
color: #000;
position: relative;
}
.collapse a.active:hover {
text-decoration: none;
}
.collapse a.active:before {
background-color: #A0C3E5;
content: "";
display: inline-block;
height: 100%;
left: 0;
position: absolute;
top: 0;
width: 3px;
}
.main h2, .main .h2 {
border-top: 0px;
padding-top: 10px;
font-size: 28px;
}
.page-header {
height: 100% !important;
}
.page-header .img-responsive {
display: inline;
}
.page-header h2 {
font-size: 32px;
display: inline;
vertical-align: bottom;
}
.navbar-brand {
padding: initial;
height: initial;
padding: 12px;
}
.navbar-header h2 {
display: inline;
position: absolute;
font-weight: bold;
margin-top: 50px ;
}
.nav > li > a.hover{
background-color: none;
}
h1, h2, h3, h4, h5, h6, .h1, .h2, .h3, .h4, .h5, .h6 {
position: relative;
}
h2 > a.anchor, h3 > a.anchor, h4 > a.anchor, h5 > a.anchor, h6 > a.anchor {
display: block;
font-weight: normal;
margin-left: -1.5ex;
position: absolute;
text-align: center;
text-decoration: none !important;
visibility: hidden;
width: 1.5ex;
z-index: 1001;
}
h2 > a.anchor:before, h3 > a.anchor:before, h4 > a.anchor:before, h5 > a.anchor:before, h6 > a.anchor:before {
content: "\f0c1";
display: block;
font-family: FontAwesome;
font-size: 0.7em;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
padding-top: 0.2em;
}
h4 > a.anchor:before, h5 > a.anchor:before, h6 > a.anchor:before {
font-size: 1em;
}
h2:hover > a.anchor,
h2 > a.anchor:hover,
h3:hover > a.anchor,
h3 > a.anchor:hover,
h4:hover > a.anchor,
h4 > a.anchor:hover,
h5:hover > a.anchor,
h5 > a.anchor:hover,
h6:hover > a.anchor,
h6 > a.anchor:hover {
visibility: visible;
}
.main {
border-left: 1px solid #e7e7e7;
margin-left: -1px;
padding-left: 25px;
}
@media (min-width: 768px) {
.main {
padding-left: 30px;
}
}
/*
* Sidebar
*/
.nav-header {
font-size: 16px;
}
.nav-header ul {
font-size: 14px;
}
.nav-header ul li a {
display: block;
padding: 5px 20px 5px 25px;
font-size: 13px;
font-weight: normal;
}
.nav-sidebar .fa {
text-align: center;
top: -1px;
width: 14px;
}
.nav-sidebar li a {
color: inherit;
}
.nav-sidebar li a:hover {
color: #000;
}
.nav-sidebar ul li ul.nav-tertiary li a {
padding-left: 50px;
}
.nav-sidebar > li > a {
padding: 7px 0;
}
.nav-sidebar > li > a:focus, .nav-sidebar > li > a:hover {
background: transparent;
}
.sidebar {
font-weight: 300;
display: none;
padding-top: 13px;
}
@media screen and (max-width: 767px) {
.sidebar {
padding-left: 30px;
padding-right: 0;
}
}
@media screen and (min-width: 768px) {
.sidebar {
border-right: 1px solid #e7e7e7;
display: block;
}
}
/*
* Off Canvas
* --------------------------------------------------
*/
body, html {
overflow-x: hidden; /* Prevent scroll on narrow devices */
font-family: "Overpass", sans-serif;
}
.toggle-nav {
margin-right: 20px;
}
@media screen and (max-width: 767px) {
.row-offcanvas {
position: relative;
-webkit-transition: all .25s ease-out;
-o-transition: all .25s ease-out;
transition: all .25s ease-out;
}
.row-offcanvas-right {
right: 0;
}
.row-offcanvas-left {
left: 0;
}
.row-offcanvas-right
.sidebar-offcanvas {
right: -75%; /* 8 columns */
}
.row-offcanvas-left
.sidebar-offcanvas {
left: -75%; /* 8 columns */
}
.row-offcanvas-right.active {
right: 75%; /* 8 columns */
}
.row-offcanvas-left.active {
left: 75%; /* 8 columns */
}
.sidebar-offcanvas {
overflow: hidden;
position: absolute;
top: 0;
width: 75%; /* 8 columns */
}
}
p {
margin: 0 0 1.6em;
}
/* Remnants of Asciidoctor default stylesheet - remove styles as needed */
#map_canvas img, #map_canvas embed, #map_canvas object, .map_canvas img, .map_canvas embed, .map_canvas object { max-width: none !important; }
.left { float: left !important; }
.right { float: right !important; }
.text-left { text-align: left !important; }
.text-right { text-align: right !important; }
.text-center { text-align: center !important; }
.text-justify { text-align: justify !important; }
.hide { display: none; }
.subheader, #content #toctitle, .admonitionblock td.content > .title, .audioblock > .title, .exampleblock > .title, .imageblock > .title, .listingblock > .title, .literalblock > .title, .stemblock > .title, .openblock > .title, .paragraph > .title, .quoteblock > .title, table.tableblock > .title, .verseblock > .title, .videoblock > .title, .dlist > .title, .olist > .title, .ulist > .title, .qlist > .title, .hdlist > .title { line-height: 1.4; color: #7a2518; font-weight: 300; margin-top: 0.2em; margin-bottom: 0.5em; }
abbr, acronym { text-transform: uppercase; font-size: 90%; color: #333333; border-bottom: 1px dotted #dddddd; cursor: help; }
abbr { text-transform: none; }
blockquote { margin: 0 0 1.25em; padding: 0.5625em 1.25em 0 1.1875em; border-left: 3px solid #487c58; }
blockquote cite { display: block; font-size: inherit; color: #454545; }
blockquote cite:before { content: "\2014 \0020"; }
blockquote cite a, blockquote cite a:visited { color: #454545; }
blockquote, blockquote p { line-height: 1.6; color: #6e6e6e; }
@media only screen and (min-width: 768px) {
#toctitle, .sidebarblock > .content > .title { line-height: 1.4; }
#toctitle, .sidebarblock > .content > .title { font-size: 1.6875em; }
}
table { background: white; margin-bottom: 1.25em; border: solid 1px #dddddd; }
table thead, table tfoot { background: whitesmoke; font-weight: bold; }
table thead tr th, table thead tr td, table tfoot tr th, table tfoot tr td { padding: 0.5em 0.625em 0.625em; font-size: inherit; color: #333333; text-align: left; }
table tr th, table tr td { padding: 0.5625em 0.625em; font-size: inherit; color: #333333; }
table tr.even, table tr.alt, table tr:nth-of-type(even) { background: #f9f9f9; }
table thead tr th, table tfoot tr th, table tbody tr td, table tr td, table tfoot tr td { display: table-cell; line-height: 1.6; }
.clearfix:before, .clearfix:after, .float-group:before, .float-group:after { content: " "; display: table; }
.clearfix:after, .float-group:after { clear: both; }
*:not(pre) > code { font-size: inherit; padding: 0; white-space: nowrap; background-color: inherit; border: 0 solid #dddddd; -webkit-border-radius: 4px; border-radius: 4px; text-shadow: none; line-height: 1; }
.keyseq { color: #666666; }
kbd:not(.keyseq) { display: inline-block; color: #333333; font-size: 0.75em; line-height: 1.4; background-color: #f7f7f7; border: 1px solid #ccc; -webkit-border-radius: 3px; border-radius: 3px; -webkit-box-shadow: 0 1px 0 rgba(0, 0, 0, 0.2), 0 0 0 2px white inset; box-shadow: 0 1px 0 rgba(0, 0, 0, 0.2), 0 0 0 2px white inset; margin: -0.15em 0.15em 0 0.15em; padding: 0.2em 0.6em 0.2em 0.5em; vertical-align: middle; white-space: nowrap; }
.keyseq kbd:first-child { margin-left: 0; }
.keyseq kbd:last-child { margin-right: 0; }
.menuseq, .menu { color: #1a1a1a; }
b.button:before, b.button:after { position: relative; top: -1px; font-weight: normal; }
b.button:before { content: "["; padding: 0 3px 0 2px; }
b.button:after { content: "]"; padding: 0 2px 0 3px; }
p a > code:hover { color: #561309; }
#header, #content, #footnotes, #footer { width: 100%; margin-left: auto; margin-right: auto; margin-top: 0; margin-bottom: 0; max-width: 62.5em; *zoom: 1; position: relative; padding-left: 0.9375em; padding-right: 0.9375em; }
#header:before, #header:after, #content:before, #content:after, #footnotes:before, #footnotes:after, #footer:before, #footer:after { content: " "; display: table; }
#header:after, #content:after, #footnotes:after, #footer:after { clear: both; }
#content:before { content: none; }
#header { margin-bottom: 2.5em; }
#header > h1 { color: black; font-weight: 300; border-bottom: 1px solid #d8d8d8; margin-bottom: -28px; padding-bottom: 32px; }
#header span { color: #6e6e6e; }
#header #revnumber { text-transform: capitalize; }
#header br { display: none; }
#header br + span { padding-left: 3px; }
#header br + span:before { content: "\2013 \0020"; }
#header br + span.author { padding-left: 0; }
#header br + span.author:before { content: ", "; }
#toc { border-bottom: 3px double #e5e5e5; padding-top: 1em; padding-bottom: 1.25em; }
#toc > ul { margin-left: 0.25em; }
#toc ul.sectlevel0 > li > a { font-style: italic; }
#toc ul.sectlevel0 ul.sectlevel1 { margin-left: 0; margin-top: 0.5em; margin-bottom: 0.5em; }
#toc ul { font-family: "Open Sans", "DejaVu Sans", "Sans", sans-serif; list-style-type: none; }
#toc a { text-decoration: none; }
#toc a:active { text-decoration: underline; }
#toctitle { color: #7a2518; }
@media only screen and (min-width: 768px) { body.toc2 { padding-left: 15em; padding-right: 0; }
#toc.toc2 { background-color: #fafaf9; position: fixed; width: 15em; left: 0; top: 0; border-right: 1px solid #e5e5e5; border-bottom: 0; z-index: 1000; padding: 1.25em 1em; height: 100%; overflow: auto; }
#toc.toc2 #toctitle { margin-top: 0; font-size: 1.2em; }
#toc.toc2 > ul { font-size: .90em; margin-bottom: 0; }
#toc.toc2 ul ul { margin-left: 0; padding-left: 1em; }
#toc.toc2 ul.sectlevel0 ul.sectlevel1 { padding-left: 0; margin-top: 0.5em; margin-bottom: 0.5em; }
body.toc2.toc-right { padding-left: 0; padding-right: 15em; }
body.toc2.toc-right #toc.toc2 { border-right: 0; border-left: 1px solid #e5e5e5; left: auto; right: 0; } }
@media only screen and (min-width: 1280px) { body.toc2 { padding-left: 20em; padding-right: 0; }
#toc.toc2 { width: 20em; }
#toc.toc2 #toctitle { font-size: 1.375em; }
#toc.toc2 > ul { font-size: 0.95em; }
#toc.toc2 ul ul { padding-left: 1.25em; }
body.toc2.toc-right { padding-left: 0; padding-right: 20em; } }
#content #toc { border-style: solid; border-width: 1px; border-color: #e3e3dd; margin-bottom: 1.25em; padding: 1.25em; background: #fafaf9; border-width: 0; -webkit-border-radius: 4px; border-radius: 4px; }
#content #toc > :first-child { margin-top: 0; }
#content #toc > :last-child { margin-bottom: 0; }
#content #toctitle { font-size: 1.375em; }
#footer { max-width: 100%; background-color: #333333; padding: 1.25em; }
#footer-text { color: #cccccc; line-height: 1.44; }
.audioblock, .imageblock, .literalblock, .listingblock, .stemblock, .verseblock, .videoblock { margin-bottom: 2.5em; }
.admonitionblock td.content > .title, .audioblock > .title, .exampleblock > .title, .imageblock > .title, .listingblock > .title, .literalblock > .title, .stemblock > .title, .openblock > .title, .paragraph > .title, .quoteblock > .title, table.tableblock > .title, .verseblock > .title, .videoblock > .title, .dlist > .title, .olist > .title, .ulist > .title, .qlist > .title, .hdlist > .title { text-rendering: optimizeLegibility; text-align: left; font-family: "Noto Serif", "DejaVu Serif", "Serif", serif; font-weight: normal; font-style: italic; }
table.tableblock > caption.title { white-space: nowrap; overflow: visible; max-width: 0; }
table.tableblock #preamble > .sectionbody > .paragraph:first-of-type p { font-size: inherit; }
.admonitionblock > table { border: 0; background: none; width: 100%; }
.admonitionblock > table td.icon { text-align: center; width: 80px; }
.admonitionblock > table td.icon img { max-width: none; }
.admonitionblock > table td.icon .title { font-weight: 300; text-transform: uppercase; }
.admonitionblock > table td.content { padding-left: 0; padding-right: 1.25em; color: #6e6e6e; }
.admonitionblock > table td.content > :last-child > :last-child { margin-bottom: 0; }
.exampleblock > .content { border-style: solid; border-width: 1px; border-color: #e6e6e6; margin-bottom: 1.25em; padding: 1.25em; background: white; -webkit-border-radius: 4px; border-radius: 4px; }
.exampleblock > .content > :first-child { margin-top: 0; }
.exampleblock > .content > :last-child { margin-bottom: 0; }
.exampleblock > .content h1, .exampleblock > .content h2, .exampleblock > .content h3, .exampleblock > .content #toctitle, .sidebarblock.exampleblock > .content > .title, .exampleblock > .content h4, .exampleblock > .content h5, .exampleblock > .content h6, .exampleblock > .content p { color: #333333; }
.exampleblock > .content h1, .exampleblock > .content h2, .exampleblock > .content h3, .exampleblock > .content #toctitle, .sidebarblock.exampleblock > .content > .title, .exampleblock > .content h4, .exampleblock > .content h5, .exampleblock > .content h6 { line-height: 1; margin-bottom: 0.625em; }
.exampleblock > .content h1.subheader, .exampleblock > .content h2.subheader, .exampleblock > .content h3.subheader, .exampleblock > .content .subheader#toctitle, .sidebarblock.exampleblock > .content > .subheader.title, .exampleblock > .content h4.subheader, .exampleblock > .content h5.subheader, .exampleblock > .content h6.subheader { line-height: 1.4; }
.exampleblock.result > .content { -webkit-box-shadow: 0 1px 8px #e3e3dd; box-shadow: 0 1px 8px #e3e3dd; }
.sidebarblock { border-style: solid; border-width: 1px; border-color: #e3e3dd; margin-top: -1.0em; margin-bottom: 1.6em; margin-left: 1em; padding: .5em; background: #F1F3F5; -webkit-border-radius: 4px; border-radius: 4px; overflow-x: auto; float: right; width: 40%; }
.sidebarblock > :first-child { margin-top: 0; }
.sidebarblock > :last-child { margin-bottom: 0; }
.sidebarblock h1, .sidebarblock h2, .sidebarblock h3, .sidebarblock #toctitle, .sidebarblock > .content > .title, .sidebarblock h4, .sidebarblock h5, .sidebarblock h6, .sidebarblock p { color: #333333; }
.sidebarblock h1, .sidebarblock h2, .sidebarblock h3, .sidebarblock #toctitle, .sidebarblock > .content > .title, .sidebarblock h4, .sidebarblock h5, .sidebarblock h6 { line-height: 1; margin-bottom: 0.625em; }
.sidebarblock h1.subheader, .sidebarblock h2.subheader, .sidebarblock h3.subheader, .sidebarblock .subheader#toctitle, .sidebarblock > .content > .subheader.title, .sidebarblock h4.subheader, .sidebarblock h5.subheader, .sidebarblock h6.subheader { line-height: 1.4; }
.sidebarblock > .content > .title { color: inherit; font-size: 28px; font-weight: 500; margin-top: 0; line-height: 1.6; }
.width50 { width: 50% ! important}
.exampleblock > .content > :last-child > :last-child, .exampleblock > .content .olist > ol > li:last-child > :last-child, .exampleblock > .content .ulist > ul > li:last-child > :last-child, .exampleblock > .content .qlist > ol > li:last-child > :last-child, .sidebarblock > .content > :last-child > :last-child, .sidebarblock > .content .olist > ol > li:last-child > :last-child, .sidebarblock > .content .ulist > ul > li:last-child > :last-child, .sidebarblock > .content .qlist > ol > li:last-child > :last-child { margin-bottom: 0; }
.literalblock pre, .literalblock pre[class], .listingblock pre, .listingblock pre[class] { border: 0px; background-color: #F0F3F5; -webkit-border-radius: 5px; border-radius: 5px; padding: 1.5em 2.5em; word-wrap: break-word; }
.literalblock pre.nowrap, .literalblock pre[class].nowrap, .listingblock pre.nowrap, .listingblock pre[class].nowrap { overflow-x: auto; white-space: pre; word-wrap: normal; }
.literalblock pre > code, .literalblock pre[class] > code, .listingblock pre > code, .listingblock pre[class] > code { display: block; }
.listingblock > .content { position: relative; }
.listingblock:hover code[class*=" language-"]:before { text-transform: uppercase; font-size: 0.9em; color: #999; position: absolute; top: 0.375em; right: 0.375em; }
.listingblock:hover code.asciidoc:before { content: "asciidoc"; }
.listingblock:hover code.clojure:before { content: "clojure"; }
.listingblock:hover code.css:before { content: "css"; }
.listingblock:hover code.go:before { content: "go"; }
.listingblock:hover code.groovy:before { content: "groovy"; }
.listingblock:hover code.html:before { content: "html"; }
.listingblock:hover code.java:before { content: "java"; }
.listingblock:hover code.javascript:before { content: "javascript"; }
.listingblock:hover code.python:before { content: "python"; }
.listingblock:hover code.ruby:before { content: "ruby"; }
.listingblock:hover code.sass:before { content: "sass"; }
.listingblock:hover code.scss:before { content: "scss"; }
.listingblock:hover code.xml:before { content: "xml"; }
.listingblock:hover code.yaml:before { content: "yaml"; }
.listingblock.terminal pre .command:before { content: attr(data-prompt); padding-right: 0.5em; color: #999; }
.listingblock.terminal pre .command:not([data-prompt]):before { content: '$'; }
table.pyhltable { border: 0; margin-bottom: 0; }
table.pyhltable td { vertical-align: top; padding-top: 0; padding-bottom: 0; }
table.pyhltable td.code { padding-left: .75em; padding-right: 0; }
.highlight.pygments .lineno, table.pyhltable td:not(.code) { color: #999; padding-left: 0; padding-right: .5em; border-right: 1px solid #d8d8d8; }
.highlight.pygments .lineno { display: inline-block; margin-right: .25em; }
table.pyhltable .linenodiv { background-color: transparent !important; padding-right: 0 !important; }
.quoteblock { margin: 0 0 1.25em 0; padding: 0.5625em 1.25em 0 1.1875em; border-left: 3px solid #487c58; }
.quoteblock blockquote { margin: 0 0 1.25em 0; padding: 0 0 0.625em 0; border: 0; }
.quoteblock blockquote > .paragraph:last-child p { margin-bottom: 0; }
.quoteblock .attribution { margin-top: -0.625em; padding-bottom: 0.625em; font-size: inherit; color: #454545; line-height: 1.6; }
.quoteblock .attribution br { display: none; }
.quoteblock .attribution cite { display: block; }
table.tableblock { max-width: 100%; }
table.tableblock td .paragraph:last-child p > p:last-child, table.tableblock th > p:last-child, table.tableblock td > p:last-child { margin-bottom: 0; }
table.spread { width: 100%; }
table.tableblock, th.tableblock, td.tableblock { border: 0 solid #dddddd; }
table.grid-all th.tableblock, table.grid-all td.tableblock { border-width: 0 1px 1px 0; }
table.grid-all tfoot > tr > th.tableblock, table.grid-all tfoot > tr > td.tableblock { border-width: 1px 1px 0 0; }
table.grid-cols th.tableblock, table.grid-cols td.tableblock { border-width: 0 1px 0 0; }
table.grid-all * > tr > .tableblock:last-child, table.grid-cols * > tr > .tableblock:last-child { border-right-width: 0; }
table.grid-rows th.tableblock, table.grid-rows td.tableblock { border-width: 0 0 1px 0; }
table.grid-all tbody > tr:last-child > th.tableblock, table.grid-all tbody > tr:last-child > td.tableblock, table.grid-all thead:last-child > tr > th.tableblock, table.grid-rows tbody > tr:last-child > th.tableblock, table.grid-rows tbody > tr:last-child > td.tableblock, table.grid-rows thead:last-child > tr > th.tableblock { border-bottom-width: 0; }
table.grid-rows tfoot > tr > th.tableblock, table.grid-rows tfoot > tr > td.tableblock { border-width: 1px 0 0 0; }
table.frame-all { border-width: 1px; }
table.frame-sides { border-width: 0 1px; }
table.frame-topbot { border-width: 1px 0; }
th.halign-left, td.halign-left { text-align: left; }
th.halign-right, td.halign-right { text-align: right; }
th.halign-center, td.halign-center { text-align: center; }
th.valign-top, td.valign-top { vertical-align: top; }
th.valign-bottom, td.valign-bottom { vertical-align: bottom; }
th.valign-middle, td.valign-middle { vertical-align: middle; }
table thead th, table tfoot th { font-weight: bold; }
tbody tr th { display: table-cell; line-height: 1.6; background: whitesmoke; }
tbody tr th, tbody tr th p, tfoot tr th, tfoot tr th p { color: #333333; font-weight: bold; }
td > div.verse { white-space: pre; }
ul.unstyled, ol.unnumbered, ul.checklist, ul.none { list-style-type: none; }
ul.unstyled, ol.unnumbered, ul.checklist { margin-left: 0.625em; }
ul.checklist li > p:first-child > .fa-check-square-o:first-child, ul.checklist li > p:first-child > input[type="checkbox"]:first-child { margin-right: 0.25em; }
ul.checklist li > p:first-child > input[type="checkbox"]:first-child { position: relative; top: 1px; }
ul.inline { margin: 0 auto 0.625em auto; margin-left: -1.375em; margin-right: 0; padding: 0; list-style: none; overflow: hidden; }
ul.inline > li { list-style: none; float: left; margin-left: 1.375em; display: block; }
ul.inline > li > * { display: block; }
.unstyled dl dt { font-weight: normal; font-style: normal; }
ol.arabic { list-style-type: decimal; }
ol.decimal { list-style-type: decimal-leading-zero; }
ol.loweralpha { list-style-type: lower-alpha; }
ol.upperalpha { list-style-type: upper-alpha; }
ol.lowerroman { list-style-type: lower-roman; }
ol.upperroman { list-style-type: upper-roman; }
ol.lowergreek { list-style-type: lower-greek; }
.hdlist > table, .colist > table { border: 0; background: none; }
.hdlist > table > tbody > tr, .colist > table > tbody > tr { background: none; }
td.hdlist1 { padding-right: .75em; font-weight: bold; }
td.hdlist1, td.hdlist2 { vertical-align: top; }
.literalblock + .colist, .listingblock + .colist { margin-top: -0.5em; }
.colist > table tr > td:first-of-type { padding: 0 .75em; line-height: 1; }
.colist > table tr > td:last-of-type { padding: 0.25em 0; }
.qanda > ol > li > p > em:only-child { color: #1d4b8f; }
.thumb, .th { line-height: 0; display: inline-block; border: solid 4px white; -webkit-box-shadow: 0 0 0 1px #dddddd; box-shadow: 0 0 0 1px #dddddd; }
.imageblock.left, .imageblock[style*="float: left"] { margin: 0.25em 0.625em 1.25em 0; }
.imageblock.right, .imageblock[style*="float: right"] { margin: 0.25em 0 1.25em 0.625em; }
.imageblock > .title { margin-bottom: 0; }
.imageblock.thumb, .imageblock.th { border-width: 6px; }
.imageblock.thumb > .title, .imageblock.th > .title { padding: 0 0.125em; }
.image.left, .image.right { margin-top: 0.25em; margin-bottom: 0.25em; display: inline-block; line-height: 0; }
.image.left { margin-right: 0.625em; }
.image.right { margin-left: 0.625em; }
a.image { text-decoration: none; }
span.footnote, span.footnoteref { vertical-align: super; font-size: 0.875em; }
span.footnote a, span.footnoteref a { text-decoration: none; }
span.footnote a:active, span.footnoteref a:active { text-decoration: underline; }
#footnotes { padding-top: 0.75em; padding-bottom: 0.75em; margin-bottom: 0.625em; }
#footnotes hr { width: 20%; min-width: 6.25em; margin: -.25em 0 .75em 0; border-width: 1px 0 0 0; }
#footnotes .footnote { padding: 0 0.375em; line-height: 1.3; font-size: 0.875em; margin-left: 1.2em; text-indent: -1.2em; margin-bottom: .2em; }
#footnotes .footnote a:first-of-type { font-weight: bold; text-decoration: none; }
#footnotes .footnote:last-of-type { margin-bottom: 0; }
#content #footnotes { margin-top: -0.625em; margin-bottom: 0; padding: 0.75em 0; }
.gist .file-data > table { border: none; background: #fff; width: 100%; margin-bottom: 0; }
.gist .file-data > table td.line-data { width: 99%; }
div.unbreakable { page-break-inside: avoid; }
.replaceable { font-style: italic; font-color: inherit; font-family: inherit; }
.parameter { font-style: italic; font-family: monospace; }
.userinput { font-weight: bold; font-family: monospace; }
.envar { font-weight: bold; font-family: monospace; font-size: 90%; }
.sysitem { font-weight: bold; font-size: 90%; }
.package { font-weight: bold; font-size: 90%; }
.filename { font-weight: bold; font-style: italic; font-size: 90%; }
.big { font-size: larger; }
.small { font-size: smaller; }
.underline { text-decoration: underline; }
.overline { text-decoration: overline; }
.line-through { text-decoration: line-through; }
.aqua { color: #00bfbf; }
.aqua-background { background-color: #00fafa; }
.black { color: black; }
.black-background { background-color: black; }
.blue { color: #0000bf; }
.blue-background { background-color: #0000fa; }
.fuchsia { color: #bf00bf; }
.fuchsia-background { background-color: #fa00fa; }
.gray { color: #606060; }
.gray-background { background-color: #7d7d7d; }
.green { color: #006000; }
.green-background { background-color: #007d00; }
.lime { color: #00bf00; }
.lime-background { background-color: #00fa00; }
.maroon { color: #600000; }
.maroon-background { background-color: #7d0000; }
.navy { color: #000060; }
.navy-background { background-color: #00007d; }
.olive { color: #606000; }
.olive-background { background-color: #7d7d00; }
.purple { color: #600060; }
.purple-background { background-color: #7d007d; }
.red { color: #bf0000; }
.red-background { background-color: #fa0000; }
.silver { color: #909090; }
.silver-background { background-color: #bcbcbc; }
.teal { color: #006060; }
.teal-background { background-color: #007d7d; }
.white { color: #bfbfbf; }
.white-background { background-color: #fafafa; }
.yellow { color: #bfbf00; }
.yellow-background { background-color: #fafa00; }
span.icon > .fa { cursor: default; }
.admonitionblock td.icon [class^="fa icon-"] { font-size: 2.5em; cursor: default; }
.admonitionblock td.icon .icon-note:before { content: "\f05a"; color: #4E9FDD; }
.admonitionblock td.icon .icon-tip:before { content: "\f0eb"; color: #2C8596; }
.admonitionblock td.icon .icon-warning:before { content: "\f071"; color: #ec7a08; }
.admonitionblock td.icon .icon-caution:before { content: "\f06d"; color: #ec7a08; }
.admonitionblock td.icon .icon-important:before { content: "\f06a"; color: #c00; }
.conum[data-value] { display: inline-block; color: white !important; background-color: #333333; -webkit-border-radius: 100px; border-radius: 100px; text-align: center; width: 20px; height: 20px; font-size: 12px; line-height: 20px; font-family: "Open Sans", "Sans", sans-serif; font-style: normal; font-weight: bold; text-indent: -1px; }
.conum[data-value] * { color: white !important; }
.conum[data-value] + b { display: none; }
.conum[data-value]:after { content: attr(data-value); }
pre .conum[data-value] { position: relative; top: -2px; }
b.conum * { color: inherit !important; }
.conum:not([data-value]):empty { display: none; }
.print-only { display: none !important; }
@media print { @page { margin: 1.25cm 0.75cm; }
* { -webkit-box-shadow: none !important; box-shadow: none !important; text-shadow: none !important; }
a, a:visited { color: inherit !important; text-decoration: underline !important; }
a[href^="http:"]:after, a[href^="https:"]:after { content: " (" attr(href) ")"; }
a[href^="#"], a[href^="#"]:visited, a[href^="mailto:"], a[href^="mailto:"]:visited { text-decoration: none !important; }
abbr[title]:after { content: " (" attr(title) ")"; }
pre, blockquote { page-break-inside: avoid; }
code { color: #191919; }
thead { display: table-header-group; }
tr, img { page-break-inside: avoid; }
img { max-width: 100% !important; }
p { orphans: 3; widows: 3; }
h2, h3, #toctitle, .sidebarblock > .content > .title, #toctitle, .sidebarblock > .content > .title { page-break-after: avoid; }
#toc, .sidebarblock { background: none !important; }
#toc { border-bottom: 1px solid #d8d8d8 !important; padding-bottom: 0 !important; }
.sect1 { padding-bottom: 0 !important; }
.sect1 + .sect1 { border: none !important; }
body.book #header { text-align: center; }
body.book #header > h1 { border: none !important; margin: 2.5em 0 1em 0; padding: 0; }
body.book #header span { line-height: 1.6; }
body.book #header br { display: block; }
body.book #header br + span { padding-left: 0; }
body.book #header br + span:before { content: none !important; }
body.book #toc { border: none !important; text-align: left !important; padding: 0 !important; }
#footer { background: none !important; }
#footer-text { color: #333333 !important; }
.hide-on-print { display: none !important; }
.print-only { display: block !important; }
.hide-for-print { display: none !important; }
.show-for-print { display: inherit !important; } }
.corner-ribbon{
width: 16em;
background: #3c6eb4 ;
position: absolute;
top: 3em;
right: -4em;
text-align: center;
line-height: 5ex;
color: #dedede;
transform: rotate(45deg);
-webkit-transform: rotate(45deg);
z-index: 999;
}
.corner-ribbon a { color: #FFFFFF; }

View file

@ -1,348 +0,0 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta content="IE=edge" http-equiv="X-UA-Compatible">
<meta content="width=device-width, initial-scale=1.0" name="viewport">
<title>Defensive Coding Guide | Defensive Coding Guide | Revision History</title>
<!-- Bootstrap -->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css">
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap-theme.min.css">
<!-- Overpass Font -->
<link rel="stylesheet" href="https://overpass-30e2.kxcdn.com/overpass.css">
<link href="../../master/_stylesheets/asciibinder.css" rel="stylesheet" />
<!-- HTML5 shim and Respond.js for IE8 support of HTML5 elements and media queries -->
<!-- WARNING: Respond.js doesn't work if you view the page via file:// -->
<!--[if lt IE 9]>
<script src="https://oss.maxcdn.com/html5shiv/3.7.2/html5shiv.min.js"></script>
<script src="https://oss.maxcdn.com/respond/1.4.2/respond.min.js"></script>
<![endif]-->
<link href="../../master/_images/favicon32x32.png" rel="shortcut icon" type="text/css">
<!--[if IE]><link rel="shortcut icon" href="../../master/_images/favicon.ico"><![endif]-->
<meta content="AsciiBinder" name="application-name">
</head>
<body>
<div class="navbar navbar-default" role="navigation">
<div class="container-fluid">
<div class="navbar-header">
<a class="navbar-brand" href="https://docs.fedoraproject.org/"><img alt="Fedora Documentation" src="../../master/_images/fedora.svg"></a>
</div>
</div>
</div>
<div class="container">
<p class="toggle-nav visible-xs pull-left">
<button class="btn btn-default btn-sm" type="button" data-toggle="offcanvas">Toggle nav</button>
</p>
<ol class="breadcrumb">
<li class="sitename">
<a href="../../index.html">Home</a>
</li>
<li class="hidden-xs active">
<a href="../en-US/index.html">Defensive Coding Guide </a>
</li>
<li class="hidden-xs active">
<a href="../en-US/index.html">Defensive Coding Guide</a>
</li>
<li class="hidden-xs active">
Revision History
</li>
</ol>
<div class="row row-offcanvas row-offcanvas-left">
<div class="col-xs-8 col-sm-3 col-md-3 sidebar sidebar-offcanvas">
<ul class="nav nav-sidebar">
<li class="nav-header">
<a class="" href="#" data-toggle="collapse" data-target="#topicGroup0">
<span id="tgSpan0" class="fa fa-angle-down"></span>Defensive Coding Guide
</a>
<ul id="topicGroup0" class="collapse in list-unstyled">
<li><a class="" href="../en-US/index.html">Book Information</a></li>
<li class="nav-header">
<a class="" href="#" data-toggle="collapse" data-target="#topicSubGroup-0-1">
<span id="sgSpan-0-1" class="fa fa-caret-right"></span>&nbsp;Programming Languages
</a>
<ul id="topicSubGroup-0-1" class="nav-tertiary list-unstyled collapse">
<li><a class="" href="../en-US/programming-languages/C.html">The C Programming Language</a></li>
<li><a class="" href="../en-US/programming-languages/CXX.html">The C++ Programming&nbsp;Language</a></li>
<li><a class="" href="../en-US/programming-languages/Java.html">The Java Programming Language</a></li>
<li><a class="" href="../en-US/programming-languages/Python.html">The Python Programming Language</a></li>
<li><a class="" href="../en-US/programming-languages/Shell.html">Shell Programming and bash</a></li>
<li><a class="" href="../en-US/programming-languages/Go.html">The Go Programming Language</a></li>
<li><a class="" href="../en-US/programming-languages/Vala.html">The Vala Programming Language</a></li>
</ul>
</li>
<li class="nav-header">
<a class="" href="#" data-toggle="collapse" data-target="#topicSubGroup-0-2">
<span id="sgSpan-0-2" class="fa fa-caret-right"></span>&nbsp;Specific Programming Tasks
</a>
<ul id="topicSubGroup-0-2" class="nav-tertiary list-unstyled collapse">
<li><a class="" href="../en-US/tasks/Tasks-Library_Design.html">Library Design</a></li>
<li><a class="" href="../en-US/tasks/Tasks-Descriptors.html">File Descriptor Management</a></li>
<li><a class="" href="../en-US/tasks/Tasks-File_System.html">File System Manipulation</a></li>
<li><a class="" href="../en-US/tasks/Tasks-Temporary_Files.html">Temporary Files</a></li>
<li><a class="" href="../en-US/tasks/Tasks-Processes.html">Processes</a></li>
<li><a class="" href="../en-US/tasks/Tasks-Serialization.html">Serialization and Deserialization</a></li>
<li><a class="" href="../en-US/tasks/Tasks-Cryptography.html">Cryptography</a></li>
<li><a class="" href="../en-US/tasks/Tasks-Packaging.html">RPM Packaging</a></li>
</ul>
</li>
<li class="nav-header">
<a class="" href="#" data-toggle="collapse" data-target="#topicSubGroup-0-3">
<span id="sgSpan-0-3" class="fa fa-caret-right"></span>&nbsp;Implementing Security Features
</a>
<ul id="topicSubGroup-0-3" class="nav-tertiary list-unstyled collapse">
<li><a class="" href="../en-US/features/Features-Authentication.html">Authentication and Authorization</a></li>
<li><a class="" href="../en-US/features/Features-TLS.html">Transport Layer Security (TLS)</a></li>
<li><a class="" href="../en-US/features/Features-HSM.html">Hardware Security Modules and Smart Cards</a></li>
</ul>
</li>
<li><a class=" active" href="../en-US/Revision_History.html">Revision History</a></li>
</ul>
</li>
</ul>
</div>
<div class="col-xs-12 col-sm-9 col-md-9 main">
<div class="page-header">
<h2>Revision History</h2>
</div>
<div class="dlist">
<dl>
<dt class="hdlist1"><code>1.5</code></dt>
<dd>
<p>Fri Dec 1 2017, Mirek Jahoda (<a href="mailto:mjahoda@redhat.com">mjahoda@redhat.com</a>)</p>
<div class="ulist">
<ul>
<li>
<p>First release in AsciiDoc</p>
</li>
<li>
<p>Many updates in the crypto-related sections</p>
</li>
<li>
<p>Grammar and typography fixes</p>
</li>
</ul>
</div>
</dd>
<dt class="hdlist1"><code>1.3-1</code></dt>
<dd>
<p>Mon Oct 13 2014, Florian Weimer (<a href="mailto:fweimer@redhat.com">fweimer@redhat.com</a>)</p>
<div class="ulist">
<ul>
<li>
<p>Go: Mention default value handling in deserialization</p>
</li>
<li>
<p>Shell: New chapter</p>
</li>
</ul>
</div>
</dd>
<dt class="hdlist1"><code>1.2-1</code></dt>
<dd>
<p>Wed Jul 16 2014, Florian Weimer (<a href="mailto:fweimer@redhat.com">fweimer@redhat.com</a>)</p>
<div class="ulist">
<ul>
<li>
<p>C: Corrected the <code>strncat</code> example</p>
</li>
<li>
<p>C: Mention mixed signed/unsigned comparisons</p>
</li>
<li>
<p>C: Unsigned overflow checking example</p>
</li>
<li>
<p>C++: <code>operator new[]</code> has been fixed in GCC</p>
</li>
<li>
<p>C++: Additional material on <code>std::string</code>, iterators</p>
</li>
<li>
<p>OpenSSL: Mention <code class="command">openssl genrsa</code> entropy issue</p>
</li>
<li>
<p>Packaging: X.509 key generation</p>
</li>
<li>
<p>Go, Vala: Add short chapters</p>
</li>
<li>
<p>Serialization: Notes on fragmentation and reassembly</p>
</li>
</ul>
</div>
</dd>
<dt class="hdlist1"><code>1.1-1</code></dt>
<dd>
<p>Tue Aug 27 2013, Eric Christensen (<a href="mailto:sparks@redhat.com">sparks@redhat.com</a>)</p>
<div class="ulist">
<ul>
<li>
<p>Add a chapter which covers some Java topics.</p>
</li>
<li>
<p>Deserialization: Warn about Java&#8217;s java.beans.XMLDecoder.</p>
</li>
<li>
<p>C: Correct the advice on array allocation
(<a href="https://bugzilla.redhat.com/show_bug.cgi?id=995595">bug 995595</a>).</p>
</li>
<li>
<p>C: Add material on global variables.</p>
</li>
</ul>
</div>
</dd>
<dt class="hdlist1"><code>1.0-1</code></dt>
<dd>
<p>Thu May 09 2013, Eric Christensen (<a href="mailto:sparks@redhat.com">sparks@redhat.com</a>)</p>
<div class="ulist">
<ul>
<li>
<p>Added more C and C++ examples.</p>
</li>
<li>
<p>TLS Client NSS: Rely on NSS 3.14 cipher suite defaults.</p>
</li>
</ul>
</div>
</dd>
<dt class="hdlist1"><code>0-1</code></dt>
<dd>
<p>Thu Mar 7 2013, Eric Christensen (<a href="mailto:sparks@redhat.com">sparks@redhat.com</a>)</p>
<div class="ulist">
<ul>
<li>
<p>Initial publication.</p>
</li>
</ul>
</div>
</dd>
</dl>
</div>
</div>
</div>
</div>
<div id="bottom" class="text-muted py-3" >
<div class="foot">
<div class="container">
<div class="row footerlinks">
<div class="col-sm-3 col-xs-6 widget">
<h3 class="widget-title">About</h3>
<div class="widget-body">
<dl>
<dd><a href="https://fedoraproject.org/wiki/Overview">About Fedora</a></dd>
<dd><a href="https://getfedora.org/en/sponsors">Sponsors</a></dd>
<dd><a href="https://fedoramagazine.org">Fedora Magazine</a></dd>
<dd><a href="https://fedoraproject.org/wiki/Legal:Main#Legal">Legal</a></dd>
</dl>
<ul class="list-inline">
<li>
<a href="https://www.facebook.com/TheFedoraProject" class="btn-social btn-outline"><i class="fa fa-fw fa-facebook"></i></a>
</li>
<li>
<a href="https://plus.google.com/112917221531140868607" class="btn-social btn-outline"><i class="fa fa-fw fa-google-plus"></i></a>
</li>
<li>
<a href="https://twitter.com/fedora" class="btn-social btn-outline"><i class="fa fa-fw fa-twitter"></i></a>
</li>
</ul>
</div>
</div>
<div class="col-sm-3 col-xs-6 widget">
<h3 class="widget-title uppercase">Download</h3>
<div class="widget-body">
<dl>
<dd><a href="https://getfedora.org/en/workstation/download">Get Fedora Workstation</a></dd>
<dd><a href="https://getfedora.org/en/server/download">Get Fedora Server</a></dd>
<dd><a href="https://getfedora.org/en/atomic/download">Get Fedora Atomic</a></dd>
<dd><a href="https://spins.fedoraproject.org">Fedora Spins</a></dd>
<dd><a href="https://labs.fedoraproject.org">Fedora Labs</a></dd>
<dd><a href="https://arm.fedoraproject.org">Fedora ARM<span class="sup">&reg;</span></a></dd>
<dd><a href="https://alt.fedoraproject.org/">Alternative Downloads</a></dd>
</dl>
</div>
</div>
<div class="col-sm-3 col-xs-6 widget">
<h3 class="widget-title">Support</h3>
<div class="widget-body">
<dl>
<dd><a href="https://fedoraproject.org/wiki/Communicating_and_getting_help">Get Help</a></dd>
<dd><a href="https://ask.fedoraproject.org/">Ask Fedora</a></dd>
<dd><a href="https://fedoraproject.org/wiki/Common_F27_bugs">Common Bugs</a></dd>
<dd><a href="https://developer.fedoraproject.org/">Fedora Developer Portal</a></dd>
<dd><a href="https://docs.fedoraproject.org/f27/install-guide/index.html">Installation Guide</a></dd>
</dl>
</div>
</div>
<div class="col-sm-3 col-xs-6 widget">
<h3 class="widget-title">Join</h3>
<div class="widget-body">
<dl>
<dd><a href="https://fedoraproject.org/wiki/Join">Join Fedora</a></dd>
<dd><a href="http://fedoraplanet.org">Planet Fedora</a></dd>
<dd><a href="https://fedoraproject.org/wiki/SIGs">Fedora SIGs</a></dd>
<dd><a href="https://admin.fedoraproject.org/accounts/">Fedora Account System</a></dd>
<dd><a href="https://fedoracommunity.org/">Fedora Community</a></dd>
</dl>
</div>
</div>
</div> <!-- /row of widgets -->
<div class="row">
<div class="col-md-2">
<div class="widget-body">
<a href="https://www.redhat.com/"><img class="rh-logo" src="../../master/_images/redhat-logo.png" alt="Red Hat Logo" /></a>
</div>
</div>
<div class="col-md-7">
<div class="widget-body">
<p class="sponsor">Fedora is sponsored by Red Hat.</p>
<p class="sponsor"><a href="https://www.redhat.com/en/technologies/linux-platforms/articles/relationship-between-fedora-and-rhel">Learn more about the relationship between Red Hat and Fedora &raquo;</a></p>
<p class="copy">&copy; 2017 Red Hat, Inc. and others. Please send any comments or corrections to the <a href="https://pagure.io/fedora-docs/docs-fp-o">documentation team</a></p>
</div>
</div>
</div> <!-- /row of widgets -->
</div>
</div>
</div>
<!-- jQuery (necessary for Bootstrap's JavaScript plugins) -->
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>
<!-- Latest compiled and minified JavaScript -->
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/js/bootstrap.min.js"></script>
<script src="../../master/_javascripts/bootstrap-offcanvas.js" type="text/javascript"></script>
<script type="text/javascript">
/*<![CDATA[*/
$(document).ready(function() {
$("[id^='topicGroup']").on('show.bs.collapse', function (event) {
if (!($(event.target).attr('id').match(/^topicSubGroup/))) {
$(this).parent().find("[id^='tgSpan']").toggleClass("fa-angle-right fa-angle-down");
}
});
$("[id^='topicGroup']").on('hide.bs.collapse', function (event) {
if (!($(event.target).attr('id').match(/^topicSubGroup/))) {
$(this).parent().find("[id^='tgSpan']").toggleClass("fa-angle-right fa-angle-down");
}
});
$("[id^='topicSubGroup']").on('show.bs.collapse', function () {
$(this).parent().find("[id^='sgSpan']").toggleClass("fa-caret-right fa-caret-down");
});
$("[id^='topicSubGroup']").on('hide.bs.collapse', function () {
$(this).parent().find("[id^='sgSpan']").toggleClass("fa-caret-right fa-caret-down");
});
});
/*]]>*/
</script>
</body>
</html>

View file

@ -1,410 +0,0 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta content="IE=edge" http-equiv="X-UA-Compatible">
<meta content="width=device-width, initial-scale=1.0" name="viewport">
<title>Defensive Coding Guide | Defensive Coding Guide | Implementing Security Features | Authentication and Authorization</title>
<!-- Bootstrap -->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css">
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap-theme.min.css">
<!-- Overpass Font -->
<link rel="stylesheet" href="https://overpass-30e2.kxcdn.com/overpass.css">
<link href="../../../master/_stylesheets/asciibinder.css" rel="stylesheet" />
<!-- HTML5 shim and Respond.js for IE8 support of HTML5 elements and media queries -->
<!-- WARNING: Respond.js doesn't work if you view the page via file:// -->
<!--[if lt IE 9]>
<script src="https://oss.maxcdn.com/html5shiv/3.7.2/html5shiv.min.js"></script>
<script src="https://oss.maxcdn.com/respond/1.4.2/respond.min.js"></script>
<![endif]-->
<link href="../../../master/_images/favicon32x32.png" rel="shortcut icon" type="text/css">
<!--[if IE]><link rel="shortcut icon" href="../../../master/_images/favicon.ico"><![endif]-->
<meta content="AsciiBinder" name="application-name">
</head>
<body>
<div class="navbar navbar-default" role="navigation">
<div class="container-fluid">
<div class="navbar-header">
<a class="navbar-brand" href="https://docs.fedoraproject.org/"><img alt="Fedora Documentation" src="../../../master/_images/fedora.svg"></a>
</div>
</div>
</div>
<div class="container">
<p class="toggle-nav visible-xs pull-left">
<button class="btn btn-default btn-sm" type="button" data-toggle="offcanvas">Toggle nav</button>
</p>
<ol class="breadcrumb">
<li class="sitename">
<a href="../../../index.html">Home</a>
</li>
<li class="hidden-xs active">
<a href="../../en-US/index.html">Defensive Coding Guide </a>
</li>
<li class="hidden-xs active">
<a href="../../en-US/index.html">Defensive Coding Guide</a>
</li>
<li class="hidden-xs active"><a href="../../en-US/features/Features-Authentication.html">Implementing Security Features</a></li>
<li class="hidden-xs active">
Authentication and Authorization
</li>
</ol>
<div class="row row-offcanvas row-offcanvas-left">
<div class="col-xs-8 col-sm-3 col-md-3 sidebar sidebar-offcanvas">
<ul class="nav nav-sidebar">
<li class="nav-header">
<a class="" href="#" data-toggle="collapse" data-target="#topicGroup0">
<span id="tgSpan0" class="fa fa-angle-down"></span>Defensive Coding Guide
</a>
<ul id="topicGroup0" class="collapse in list-unstyled">
<li><a class="" href="../../en-US/index.html">Book Information</a></li>
<li class="nav-header">
<a class="" href="#" data-toggle="collapse" data-target="#topicSubGroup-0-1">
<span id="sgSpan-0-1" class="fa fa-caret-right"></span>&nbsp;Programming Languages
</a>
<ul id="topicSubGroup-0-1" class="nav-tertiary list-unstyled collapse">
<li><a class="" href="../../en-US/programming-languages/C.html">The C Programming Language</a></li>
<li><a class="" href="../../en-US/programming-languages/CXX.html">The C++ Programming&nbsp;Language</a></li>
<li><a class="" href="../../en-US/programming-languages/Java.html">The Java Programming Language</a></li>
<li><a class="" href="../../en-US/programming-languages/Python.html">The Python Programming Language</a></li>
<li><a class="" href="../../en-US/programming-languages/Shell.html">Shell Programming and bash</a></li>
<li><a class="" href="../../en-US/programming-languages/Go.html">The Go Programming Language</a></li>
<li><a class="" href="../../en-US/programming-languages/Vala.html">The Vala Programming Language</a></li>
</ul>
</li>
<li class="nav-header">
<a class="" href="#" data-toggle="collapse" data-target="#topicSubGroup-0-2">
<span id="sgSpan-0-2" class="fa fa-caret-right"></span>&nbsp;Specific Programming Tasks
</a>
<ul id="topicSubGroup-0-2" class="nav-tertiary list-unstyled collapse">
<li><a class="" href="../../en-US/tasks/Tasks-Library_Design.html">Library Design</a></li>
<li><a class="" href="../../en-US/tasks/Tasks-Descriptors.html">File Descriptor Management</a></li>
<li><a class="" href="../../en-US/tasks/Tasks-File_System.html">File System Manipulation</a></li>
<li><a class="" href="../../en-US/tasks/Tasks-Temporary_Files.html">Temporary Files</a></li>
<li><a class="" href="../../en-US/tasks/Tasks-Processes.html">Processes</a></li>
<li><a class="" href="../../en-US/tasks/Tasks-Serialization.html">Serialization and Deserialization</a></li>
<li><a class="" href="../../en-US/tasks/Tasks-Cryptography.html">Cryptography</a></li>
<li><a class="" href="../../en-US/tasks/Tasks-Packaging.html">RPM Packaging</a></li>
</ul>
</li>
<li class="nav-header">
<a class="" href="#" data-toggle="collapse" data-target="#topicSubGroup-0-3">
<span id="sgSpan-0-3" class="fa fa-caret-down"></span>&nbsp;Implementing Security Features
</a>
<ul id="topicSubGroup-0-3" class="nav-tertiary list-unstyled collapse in">
<li><a class=" active" href="../../en-US/features/Features-Authentication.html">Authentication and Authorization</a></li>
<li><a class="" href="../../en-US/features/Features-TLS.html">Transport Layer Security (TLS)</a></li>
<li><a class="" href="../../en-US/features/Features-HSM.html">Hardware Security Modules and Smart Cards</a></li>
</ul>
</li>
<li><a class="" href="../../en-US/Revision_History.html">Revision History</a></li>
</ul>
</li>
</ul>
</div>
<div class="col-xs-12 col-sm-9 col-md-9 main">
<div class="page-header">
<h2>Authentication and Authorization</h2>
</div>
<div class="sect1">
<h2 id="sect-Defensive_Coding-Authentication-Server"><a class="anchor" href="#sect-Defensive_Coding-Authentication-Server"></a>Authenticating Servers</h2>
<div class="sectionbody">
<div class="paragraph">
<p>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:</p>
</div>
<div class="ulist">
<ul>
<li>
<p>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.</p>
</li>
<li>
<p>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.</p>
</li>
<li>
<p>On Linux, UNIX domain sockets (of the
<code>PF_UNIX</code> protocol family, sometimes called
<code>PF_LOCAL</code>) are restricted by file system
permissions. If the server socket path is not
world-writable, the server identity cannot be spoofed by
local users.</p>
</li>
<li>
<p>Port numbers less than 1024 (<strong>trusted
ports</strong>) can only be used by
<code>root</code>, 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.)</p>
</li>
</ul>
</div>
<div class="paragraph">
<p>TLS (<a href="#chap-Defensive_Coding-TLS">[chap-Defensive_Coding-TLS]</a>) is the
recommended way for securing connections over untrusted
networks.</p>
</div>
<div class="paragraph">
<p>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.</p>
</div>
</div>
</div>
<div class="sect1">
<h2 id="sect-Defensive_Coding-Authentication-Host_based"><a class="anchor" href="#sect-Defensive_Coding-Authentication-Host_based"></a>Host-based Authentication</h2>
<div class="sectionbody">
<div class="paragraph">
<p>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
<code>/etc/hosts</code>). 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.)</p>
</div>
<div class="paragraph">
<p>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.</p>
</div>
<div class="paragraph">
<p>The names returned by <code>gethostbyaddr</code> and
<code>getnameinfo</code> 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
<code>gethostbyaddr</code> or
<code>getaddrinfo</code> has to be performed. The name
is only valid if the original address is found among the results
of the forward lookup (<strong>double-reverse
lookup</strong>).</p>
</div>
<div class="paragraph">
<p>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.</p>
</div>
<div class="paragraph">
<p>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.</p>
</div>
<div class="paragraph">
<p>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.</p>
</div>
</div>
</div>
<div class="sect1">
<h2 id="sect-Defensive_Coding-Authentication-UNIX_Domain"><a class="anchor" href="#sect-Defensive_Coding-Authentication-UNIX_Domain"></a>UNIX Domain Socket Authentication</h2>
<div class="sectionbody">
<div class="paragraph">
<p>UNIX domain sockets (with address family
<code>AF_UNIX</code> or <code>AF_LOCAL</code>) are
restricted to the local host and offer a special authentication
mechanism: credentials passing.</p>
</div>
<div class="paragraph">
<p>Nowadays, most systems support the
<code>SO_PEERCRED</code> (Linux) or
<code>LOCAL_PEERCRED</code> (FreeBSD) socket options, or
the <code>getpeereid</code> (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.</p>
</div>
<div class="paragraph">
<p>Historically, credentials passing was implemented using
ancillary data in the <code>sendmsg</code> and
<code>recvmsg</code> 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.</p>
</div>
<div class="paragraph">
<p>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
<code>getpwuid</code> (or
<code>getpwuid_r</code>) and
<code>getgrouplist</code>. Using the PID and
information from <code>/proc/PID/status</code> is prone
to race conditions and insecure.</p>
</div>
</div>
</div>
<div class="sect1">
<h2 id="sect-Defensive_Coding-Authentication-Netlink"><a class="anchor" href="#sect-Defensive_Coding-Authentication-Netlink"></a><code>AF_NETLINK</code> Authentication of Origin</h2>
<div class="sectionbody">
<div class="paragraph">
<p>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.</p>
</div>
<div class="paragraph">
<p>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
<code>nl_pid</code> in the <code>sockaddr_nl</code>
structure is <code>0</code>. (This structure can be
obtained using <code>recvfrom</code> or
<code>recvmsg</code>, it is different from the
<code>nlmsghdr</code> structure.) The kernel does not
prevent other processes from sending unicast Netlink messages,
but the <code>nl_pid</code> field in the sender&#8217;s socket
address will be non-zero in such cases.</p>
</div>
<div class="paragraph">
<p>Applications should not use <code>AF_NETLINK</code>
sockets as an IPC mechanism among processes, but prefer UNIX
domain sockets for this tasks.</p>
</div>
</div>
</div>
</div>
</div>
</div>
<div id="bottom" class="text-muted py-3" >
<div class="foot">
<div class="container">
<div class="row footerlinks">
<div class="col-sm-3 col-xs-6 widget">
<h3 class="widget-title">About</h3>
<div class="widget-body">
<dl>
<dd><a href="https://fedoraproject.org/wiki/Overview">About Fedora</a></dd>
<dd><a href="https://getfedora.org/en/sponsors">Sponsors</a></dd>
<dd><a href="https://fedoramagazine.org">Fedora Magazine</a></dd>
<dd><a href="https://fedoraproject.org/wiki/Legal:Main#Legal">Legal</a></dd>
</dl>
<ul class="list-inline">
<li>
<a href="https://www.facebook.com/TheFedoraProject" class="btn-social btn-outline"><i class="fa fa-fw fa-facebook"></i></a>
</li>
<li>
<a href="https://plus.google.com/112917221531140868607" class="btn-social btn-outline"><i class="fa fa-fw fa-google-plus"></i></a>
</li>
<li>
<a href="https://twitter.com/fedora" class="btn-social btn-outline"><i class="fa fa-fw fa-twitter"></i></a>
</li>
</ul>
</div>
</div>
<div class="col-sm-3 col-xs-6 widget">
<h3 class="widget-title uppercase">Download</h3>
<div class="widget-body">
<dl>
<dd><a href="https://getfedora.org/en/workstation/download">Get Fedora Workstation</a></dd>
<dd><a href="https://getfedora.org/en/server/download">Get Fedora Server</a></dd>
<dd><a href="https://getfedora.org/en/atomic/download">Get Fedora Atomic</a></dd>
<dd><a href="https://spins.fedoraproject.org">Fedora Spins</a></dd>
<dd><a href="https://labs.fedoraproject.org">Fedora Labs</a></dd>
<dd><a href="https://arm.fedoraproject.org">Fedora ARM<span class="sup">&reg;</span></a></dd>
<dd><a href="https://alt.fedoraproject.org/">Alternative Downloads</a></dd>
</dl>
</div>
</div>
<div class="col-sm-3 col-xs-6 widget">
<h3 class="widget-title">Support</h3>
<div class="widget-body">
<dl>
<dd><a href="https://fedoraproject.org/wiki/Communicating_and_getting_help">Get Help</a></dd>
<dd><a href="https://ask.fedoraproject.org/">Ask Fedora</a></dd>
<dd><a href="https://fedoraproject.org/wiki/Common_F27_bugs">Common Bugs</a></dd>
<dd><a href="https://developer.fedoraproject.org/">Fedora Developer Portal</a></dd>
<dd><a href="https://docs.fedoraproject.org/f27/install-guide/index.html">Installation Guide</a></dd>
</dl>
</div>
</div>
<div class="col-sm-3 col-xs-6 widget">
<h3 class="widget-title">Join</h3>
<div class="widget-body">
<dl>
<dd><a href="https://fedoraproject.org/wiki/Join">Join Fedora</a></dd>
<dd><a href="http://fedoraplanet.org">Planet Fedora</a></dd>
<dd><a href="https://fedoraproject.org/wiki/SIGs">Fedora SIGs</a></dd>
<dd><a href="https://admin.fedoraproject.org/accounts/">Fedora Account System</a></dd>
<dd><a href="https://fedoracommunity.org/">Fedora Community</a></dd>
</dl>
</div>
</div>
</div> <!-- /row of widgets -->
<div class="row">
<div class="col-md-2">
<div class="widget-body">
<a href="https://www.redhat.com/"><img class="rh-logo" src="../../../master/_images/redhat-logo.png" alt="Red Hat Logo" /></a>
</div>
</div>
<div class="col-md-7">
<div class="widget-body">
<p class="sponsor">Fedora is sponsored by Red Hat.</p>
<p class="sponsor"><a href="https://www.redhat.com/en/technologies/linux-platforms/articles/relationship-between-fedora-and-rhel">Learn more about the relationship between Red Hat and Fedora &raquo;</a></p>
<p class="copy">&copy; 2017 Red Hat, Inc. and others. Please send any comments or corrections to the <a href="https://pagure.io/fedora-docs/docs-fp-o">documentation team</a></p>
</div>
</div>
</div> <!-- /row of widgets -->
</div>
</div>
</div>
<!-- jQuery (necessary for Bootstrap's JavaScript plugins) -->
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>
<!-- Latest compiled and minified JavaScript -->
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/js/bootstrap.min.js"></script>
<script src="../../../master/_javascripts/bootstrap-offcanvas.js" type="text/javascript"></script>
<script type="text/javascript">
/*<![CDATA[*/
$(document).ready(function() {
$("[id^='topicGroup']").on('show.bs.collapse', function (event) {
if (!($(event.target).attr('id').match(/^topicSubGroup/))) {
$(this).parent().find("[id^='tgSpan']").toggleClass("fa-angle-right fa-angle-down");
}
});
$("[id^='topicGroup']").on('hide.bs.collapse', function (event) {
if (!($(event.target).attr('id').match(/^topicSubGroup/))) {
$(this).parent().find("[id^='tgSpan']").toggleClass("fa-angle-right fa-angle-down");
}
});
$("[id^='topicSubGroup']").on('show.bs.collapse', function () {
$(this).parent().find("[id^='sgSpan']").toggleClass("fa-caret-right fa-caret-down");
});
$("[id^='topicSubGroup']").on('hide.bs.collapse', function () {
$(this).parent().find("[id^='sgSpan']").toggleClass("fa-caret-right fa-caret-down");
});
});
/*]]>*/
</script>
</body>
</html>

View file

@ -1,617 +0,0 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta content="IE=edge" http-equiv="X-UA-Compatible">
<meta content="width=device-width, initial-scale=1.0" name="viewport">
<title>Defensive Coding Guide | Defensive Coding Guide | Implementing Security Features | Hardware Security Modules and Smart Cards</title>
<!-- Bootstrap -->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css">
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap-theme.min.css">
<!-- Overpass Font -->
<link rel="stylesheet" href="https://overpass-30e2.kxcdn.com/overpass.css">
<link href="../../../master/_stylesheets/asciibinder.css" rel="stylesheet" />
<!-- HTML5 shim and Respond.js for IE8 support of HTML5 elements and media queries -->
<!-- WARNING: Respond.js doesn't work if you view the page via file:// -->
<!--[if lt IE 9]>
<script src="https://oss.maxcdn.com/html5shiv/3.7.2/html5shiv.min.js"></script>
<script src="https://oss.maxcdn.com/respond/1.4.2/respond.min.js"></script>
<![endif]-->
<link href="../../../master/_images/favicon32x32.png" rel="shortcut icon" type="text/css">
<!--[if IE]><link rel="shortcut icon" href="../../../master/_images/favicon.ico"><![endif]-->
<meta content="AsciiBinder" name="application-name">
</head>
<body>
<div class="navbar navbar-default" role="navigation">
<div class="container-fluid">
<div class="navbar-header">
<a class="navbar-brand" href="https://docs.fedoraproject.org/"><img alt="Fedora Documentation" src="../../../master/_images/fedora.svg"></a>
</div>
</div>
</div>
<div class="container">
<p class="toggle-nav visible-xs pull-left">
<button class="btn btn-default btn-sm" type="button" data-toggle="offcanvas">Toggle nav</button>
</p>
<ol class="breadcrumb">
<li class="sitename">
<a href="../../../index.html">Home</a>
</li>
<li class="hidden-xs active">
<a href="../../en-US/index.html">Defensive Coding Guide </a>
</li>
<li class="hidden-xs active">
<a href="../../en-US/index.html">Defensive Coding Guide</a>
</li>
<li class="hidden-xs active"><a href="../../en-US/features/Features-Authentication.html">Implementing Security Features</a></li>
<li class="hidden-xs active">
Hardware Security Modules and Smart Cards
</li>
</ol>
<div class="row row-offcanvas row-offcanvas-left">
<div class="col-xs-8 col-sm-3 col-md-3 sidebar sidebar-offcanvas">
<ul class="nav nav-sidebar">
<li class="nav-header">
<a class="" href="#" data-toggle="collapse" data-target="#topicGroup0">
<span id="tgSpan0" class="fa fa-angle-down"></span>Defensive Coding Guide
</a>
<ul id="topicGroup0" class="collapse in list-unstyled">
<li><a class="" href="../../en-US/index.html">Book Information</a></li>
<li class="nav-header">
<a class="" href="#" data-toggle="collapse" data-target="#topicSubGroup-0-1">
<span id="sgSpan-0-1" class="fa fa-caret-right"></span>&nbsp;Programming Languages
</a>
<ul id="topicSubGroup-0-1" class="nav-tertiary list-unstyled collapse">
<li><a class="" href="../../en-US/programming-languages/C.html">The C Programming Language</a></li>
<li><a class="" href="../../en-US/programming-languages/CXX.html">The C++ Programming&nbsp;Language</a></li>
<li><a class="" href="../../en-US/programming-languages/Java.html">The Java Programming Language</a></li>
<li><a class="" href="../../en-US/programming-languages/Python.html">The Python Programming Language</a></li>
<li><a class="" href="../../en-US/programming-languages/Shell.html">Shell Programming and bash</a></li>
<li><a class="" href="../../en-US/programming-languages/Go.html">The Go Programming Language</a></li>
<li><a class="" href="../../en-US/programming-languages/Vala.html">The Vala Programming Language</a></li>
</ul>
</li>
<li class="nav-header">
<a class="" href="#" data-toggle="collapse" data-target="#topicSubGroup-0-2">
<span id="sgSpan-0-2" class="fa fa-caret-right"></span>&nbsp;Specific Programming Tasks
</a>
<ul id="topicSubGroup-0-2" class="nav-tertiary list-unstyled collapse">
<li><a class="" href="../../en-US/tasks/Tasks-Library_Design.html">Library Design</a></li>
<li><a class="" href="../../en-US/tasks/Tasks-Descriptors.html">File Descriptor Management</a></li>
<li><a class="" href="../../en-US/tasks/Tasks-File_System.html">File System Manipulation</a></li>
<li><a class="" href="../../en-US/tasks/Tasks-Temporary_Files.html">Temporary Files</a></li>
<li><a class="" href="../../en-US/tasks/Tasks-Processes.html">Processes</a></li>
<li><a class="" href="../../en-US/tasks/Tasks-Serialization.html">Serialization and Deserialization</a></li>
<li><a class="" href="../../en-US/tasks/Tasks-Cryptography.html">Cryptography</a></li>
<li><a class="" href="../../en-US/tasks/Tasks-Packaging.html">RPM Packaging</a></li>
</ul>
</li>
<li class="nav-header">
<a class="" href="#" data-toggle="collapse" data-target="#topicSubGroup-0-3">
<span id="sgSpan-0-3" class="fa fa-caret-down"></span>&nbsp;Implementing Security Features
</a>
<ul id="topicSubGroup-0-3" class="nav-tertiary list-unstyled collapse in">
<li><a class="" href="../../en-US/features/Features-Authentication.html">Authentication and Authorization</a></li>
<li><a class="" href="../../en-US/features/Features-TLS.html">Transport Layer Security (TLS)</a></li>
<li><a class=" active" href="../../en-US/features/Features-HSM.html">Hardware Security Modules and Smart Cards</a></li>
</ul>
</li>
<li><a class="" href="../../en-US/Revision_History.html">Revision History</a></li>
</ul>
</li>
</ul>
</div>
<div class="col-xs-12 col-sm-9 col-md-9 main">
<div class="page-header">
<h2>Hardware Security Modules and Smart Cards</h2>
</div>
<div id="preamble">
<div class="sectionbody">
<div class="paragraph">
<p>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.</p>
</div>
<div class="paragraph">
<p>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.</p>
</div>
<div class="paragraph">
<p>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 <code>opensc</code>
shared module (<code>opensc-pkcs11.so</code>) can be used for the majority
of smart cards available in the market. By convention these modules are located
at <code>/usr/lib64/pkcs11</code>. They can be used directly, or via
a higher level library.</p>
</div>
<div class="paragraph">
<p>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.</p>
</div>
<div class="ulist">
<ul>
<li>
<p>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 <a href="https://p11-glue.freedesktop.org/doc/p11-kit/pkcs11-conf.html">p11-kit
configuration files</a>, stored at <code>/etc/pkcs11/modules/</code>. For applications using
<code>engine_pkcs11</code> or GnuTLS the registered modules are
available without further configuration. Other applications will have to load
the <code>p11-kit-proxy.so</code> module.</p>
</li>
<li>
<p>Most crypto libraries support the <a href="https://tools.ietf.org/html/rfc7512">PKCS#11 URLs scheme</a>
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.</p>
</li>
<li>
<p>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.</p>
</li>
<li>
<p>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 <code>softhsm</code> which
provides a tool to setup a software HSM, and a PKCS#11 library.</p>
</li>
<li>
<p>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 <code>softhsm</code> 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.</p>
</li>
</ul>
</div>
</div>
</div>
<div class="sect1">
<h2 id="sect-Defensive_Coding-HSM-OpenSSL"><a class="anchor" href="#sect-Defensive_Coding-HSM-OpenSSL"></a>OpenSSL HSM Support</h2>
<div class="sectionbody">
<div class="paragraph">
<p>OpenSSL does not have native support for PKCS#11. It can
provide PKCS#11 support through the OpenSC&#8217;s project
<code>pkcs11</code> engine (formerly known as <code>engine_pkcs11</code>).
As such software intended to use HSMs, must utilize that engine.</p>
</div>
<div class="paragraph">
<p>Engine <code>pkcs11</code> 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 <code>p11-kit-proxy.so</code>.</p>
</div>
<div class="paragraph">
<p>The following example demonstrates the initialization of the pkcs11 engine
and its usage to sign data.</p>
</div>
<div id="ex-Defensive_Coding-HSM-OpenSSL" class="exampleblock">
<div class="title">Example 1. Signing data with HSM and OpenSSL</div>
<div class="content">
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code data-lang="c">OpenSSL_add_all_algorithms();
ERR_load_crypto_strings();
ERR_clear_error();
ENGINE_load_builtin_engines();
e = ENGINE_by_id(<span style="background-color:hsla(0,100%,50%,0.05)"><span style="color:#710">&quot;</span><span style="color:#D20">pkcs11</span><span style="color:#710">&quot;</span></span>);
<span style="color:#080;font-weight:bold">if</span> (!e) {
display_openssl_errors(__LINE__);
exit(<span style="color:#00D">1</span>);
}
<span style="color:#080;font-weight:bold">if</span> (module_path) {
fprintf(stderr, <span style="background-color:hsla(0,100%,50%,0.05)"><span style="color:#710">&quot;</span><span style="color:#D20">loading: %s</span><span style="color:#b0b">\n</span><span style="color:#710">&quot;</span></span>, module_path);
<span style="color:#080;font-weight:bold">if</span> (!ENGINE_ctrl_cmd_string(e, <span style="background-color:hsla(0,100%,50%,0.05)"><span style="color:#710">&quot;</span><span style="color:#D20">MODULE_PATH</span><span style="color:#710">&quot;</span></span>, module_path, <span style="color:#00D">0</span>)) {
display_openssl_errors(__LINE__);
exit(<span style="color:#00D">1</span>);
}
}
<span style="color:#080;font-weight:bold">if</span> (!ENGINE_init(e)) {
display_openssl_errors(__LINE__);
exit(<span style="color:#00D">1</span>);
}
<span style="color:#080;font-weight:bold">if</span> (key_pass &amp;&amp; !ENGINE_ctrl_cmd_string(e, <span style="background-color:hsla(0,100%,50%,0.05)"><span style="color:#710">&quot;</span><span style="color:#D20">PIN</span><span style="color:#710">&quot;</span></span>, key_pass, <span style="color:#00D">0</span>)) {
display_openssl_errors(__LINE__);
exit(<span style="color:#00D">1</span>);
}
private_key = ENGINE_load_private_key(e, private_key_name, <span style="color:#069">NULL</span>, <span style="color:#069">NULL</span>);
<span style="color:#080;font-weight:bold">if</span> (!private_key) {
fprintf(stderr, <span style="background-color:hsla(0,100%,50%,0.05)"><span style="color:#710">&quot;</span><span style="color:#D20">cannot load: %s</span><span style="color:#b0b">\n</span><span style="color:#710">&quot;</span></span>, private_key_name);
display_openssl_errors(__LINE__);
exit(<span style="color:#00D">1</span>);
}
display_openssl_errors(__LINE__);
digest_algo = EVP_get_digestbyname(<span style="background-color:hsla(0,100%,50%,0.05)"><span style="color:#710">&quot;</span><span style="color:#D20">sha256</span><span style="color:#710">&quot;</span></span>);
EVP_MD_CTX_init(&amp;ctx);
<span style="color:#080;font-weight:bold">if</span> (EVP_DigestInit(&amp;ctx, digest_algo) &lt;= <span style="color:#00D">0</span>) {
display_openssl_errors(__LINE__);
exit(<span style="color:#00D">1</span>);
}
EVP_SignInit(&amp;ctx, digest_algo);
<span style="color:#579">#define</span> TEST_DATA <span style="background-color:hsla(0,100%,50%,0.05)"><span style="color:#710">&quot;</span><span style="color:#D20">test data</span><span style="color:#710">&quot;</span></span>
<span style="color:#080;font-weight:bold">if</span> (EVP_SignUpdate(&amp;ctx, TEST_DATA, <span style="color:#080;font-weight:bold">sizeof</span>(TEST_DATA) - <span style="color:#00D">1</span>) &lt;= <span style="color:#00D">0</span>) {
display_openssl_errors(__LINE__);
exit(<span style="color:#00D">1</span>);
}
n = <span style="color:#080;font-weight:bold">sizeof</span>(buf);
<span style="color:#080;font-weight:bold">if</span> (EVP_SignFinal(&amp;ctx, buf, &amp;n, private_key) &lt;= <span style="color:#00D">0</span>) {
display_openssl_errors(__LINE__);
exit(<span style="color:#00D">1</span>);
}
EVP_PKEY_free(private_key);
ENGINE_finish(e);</code></pre>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="sect-Defensive_Coding-HSM-GNUTLS"><a class="anchor" href="#sect-Defensive_Coding-HSM-GNUTLS"></a>GnuTLS HSM Support</h2>
<div class="sectionbody">
<div class="paragraph">
<p>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.</p>
</div>
<div class="paragraph">
<p>The following example demonstrates the initialization of the pkcs11 engine
and its usage to sign data.</p>
</div>
<div id="ex-Defensive_Coding-HSM-GNUTLS" class="exampleblock">
<div class="title">Example 2. Signing data with HSM and GnuTLS</div>
<div class="content">
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code data-lang="c"><span style="color:#080;font-weight:bold">if</span> (module_path) {
ret = gnutls_pkcs11_init(GNUTLS_PKCS11_FLAG_MANUAL, <span style="color:#069">NULL</span>);
<span style="color:#080;font-weight:bold">if</span> (ret &lt; <span style="color:#00D">0</span>) {
fprintf(stderr, <span style="background-color:hsla(0,100%,50%,0.05)"><span style="color:#710">&quot;</span><span style="color:#D20">error in %d: %s</span><span style="color:#b0b">\n</span><span style="color:#710">&quot;</span></span>, __LINE__, gnutls_strerror(ret));
exit(<span style="color:#00D">1</span>);
}
ret = gnutls_pkcs11_add_provider(module_path, <span style="color:#069">NULL</span>);
<span style="color:#080;font-weight:bold">if</span> (ret &lt; <span style="color:#00D">0</span>) {
fprintf(stderr, <span style="background-color:hsla(0,100%,50%,0.05)"><span style="color:#710">&quot;</span><span style="color:#D20">error in %d: %s</span><span style="color:#b0b">\n</span><span style="color:#710">&quot;</span></span>, __LINE__, gnutls_strerror(ret));
exit(<span style="color:#00D">1</span>);
}
}
<span style="color:#080;font-weight:bold">if</span> (key_pass)
gnutls_pkcs11_set_pin_function(pin_function, key_pass);
ret = gnutls_privkey_init(&amp;private_key);
<span style="color:#080;font-weight:bold">if</span> (ret &lt; <span style="color:#00D">0</span>) {
fprintf(stderr, <span style="background-color:hsla(0,100%,50%,0.05)"><span style="color:#710">&quot;</span><span style="color:#D20">error in %d: %s</span><span style="color:#b0b">\n</span><span style="color:#710">&quot;</span></span>, __LINE__, gnutls_strerror(ret));
exit(<span style="color:#00D">1</span>);
}
ret = gnutls_privkey_import_url(private_key, private_key_name, <span style="color:#00D">0</span>);
<span style="color:#080;font-weight:bold">if</span> (ret &lt; <span style="color:#00D">0</span>) {
fprintf(stderr, <span style="background-color:hsla(0,100%,50%,0.05)"><span style="color:#710">&quot;</span><span style="color:#D20">error in %d: %s</span><span style="color:#b0b">\n</span><span style="color:#710">&quot;</span></span>, __LINE__, gnutls_strerror(ret));
exit(<span style="color:#00D">1</span>);
}
ret = gnutls_privkey_sign_data(private_key, GNUTLS_DIG_SHA256, <span style="color:#00D">0</span>,
&amp;testdata, &amp;signature);
<span style="color:#080;font-weight:bold">if</span> (ret &lt; <span style="color:#00D">0</span>) {
fprintf(stderr, <span style="background-color:hsla(0,100%,50%,0.05)"><span style="color:#710">&quot;</span><span style="color:#D20">error in %d: %s</span><span style="color:#b0b">\n</span><span style="color:#710">&quot;</span></span>, __LINE__, gnutls_strerror(ret));
exit(<span style="color:#00D">1</span>);
}
gnutls_privkey_deinit(private_key);
gnutls_free(signature.data);</code></pre>
</div>
</div>
</div>
</div>
<div class="paragraph">
<p>The PIN callback function can be either set globally as in
the example above or locally by utilizing functions such as <code>gnutls_privkey_set_pin_function</code>.
An example PIN callback function is shown below.</p>
</div>
<div id="ex-Defensive_Coding-HSM-GNUTLS-PIN" class="exampleblock">
<div class="title">Example 3. An example PIN callback with GNUTLS</div>
<div class="content">
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code data-lang="c"><span style="color:#0a8;font-weight:bold">int</span> pin_function(<span style="color:#088;font-weight:bold">void</span> *userdata, <span style="color:#0a8;font-weight:bold">int</span> attempt, <span style="color:#088;font-weight:bold">const</span> <span style="color:#0a8;font-weight:bold">char</span> *token_url,
<span style="color:#088;font-weight:bold">const</span> <span style="color:#0a8;font-weight:bold">char</span> *token_label, <span style="color:#0a8;font-weight:bold">unsigned</span> flags, <span style="color:#0a8;font-weight:bold">char</span> *pin, size_t pin_max)
{
<span style="color:#080;font-weight:bold">if</span> (flags &amp; GNUTLS_PIN_FINAL_TRY)
printf(<span style="background-color:hsla(0,100%,50%,0.05)"><span style="color:#710">&quot;</span><span style="color:#D20">This is the final try before locking!</span><span style="color:#b0b">\n</span><span style="color:#710">&quot;</span></span>);
<span style="color:#080;font-weight:bold">if</span> (flags &amp; GNUTLS_PIN_COUNT_LOW)
printf(<span style="background-color:hsla(0,100%,50%,0.05)"><span style="color:#710">&quot;</span><span style="color:#D20">Only few tries left before locking!</span><span style="color:#b0b">\n</span><span style="color:#710">&quot;</span></span>);
<span style="color:#080;font-weight:bold">if</span> (flags &amp; GNUTLS_PIN_WRONG)
printf(<span style="background-color:hsla(0,100%,50%,0.05)"><span style="color:#710">&quot;</span><span style="color:#D20">Wrong PIN has been provided in the previous attempt</span><span style="color:#b0b">\n</span><span style="color:#710">&quot;</span></span>);
<span style="color:#777">/* userdata is the second value passed to gnutls_pkcs11_set_pin_function()
* in this example we passed the PIN as a null terminated value.
*/</span>
snprintf(pin, pin_max, <span style="background-color:hsla(0,100%,50%,0.05)"><span style="color:#710">&quot;</span><span style="color:#D20">%s</span><span style="color:#710">&quot;</span></span>, (<span style="color:#0a8;font-weight:bold">char</span>*)userdata);
<span style="color:#080;font-weight:bold">return</span> <span style="color:#00D">0</span>;
}</code></pre>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="sect-Defensive_Coding-HSM-NSS"><a class="anchor" href="#sect-Defensive_Coding-HSM-NSS"></a>NSS HSM Support</h2>
<div class="sectionbody">
<div class="paragraph">
<p>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.</p>
</div>
<div class="paragraph">
<p>The following example demonstrates a typical NSS application for signing.</p>
</div>
<div id="ex-Defensive_Coding-HSM-NSS" class="exampleblock">
<div class="title">Example 4. Signing data with HSM and NSS</div>
<div class="content">
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code data-lang="c">SECStatus rv;
CERTCertificate *cert = <span style="color:#069">NULL</span>;
SECKEYPrivateKey *pvtkey = <span style="color:#069">NULL</span>;
SECItem signature = { siBuffer, <span style="color:#069">NULL</span>, <span style="color:#00D">0</span> };
SECOidTag algTag;
<span style="color:#0a8;font-weight:bold">int</span> r = <span style="color:#00D">1</span>;
<span style="color:#0a8;font-weight:bold">unsigned</span> <span style="color:#0a8;font-weight:bold">char</span> buf[] = <span style="background-color:hsla(0,100%,50%,0.05)"><span style="color:#710">&quot;</span><span style="color:#D20">test data to sign</span><span style="color:#710">&quot;</span></span>;
<span style="color:#088;font-weight:bold">const</span> <span style="color:#0a8;font-weight:bold">char</span> *cert_name;
<span style="color:#0a8;font-weight:bold">unsigned</span> i;
<span style="color:#080;font-weight:bold">if</span> (argc &lt; <span style="color:#00D">3</span>) {
fprintf(stderr, <span style="background-color:hsla(0,100%,50%,0.05)"><span style="color:#710">&quot;</span><span style="color:#D20">usage: %s [cert name] [PIN]</span><span style="color:#b0b">\n</span><span style="color:#b0b">\n</span><span style="color:#710">&quot;</span></span>, argv[<span style="color:#00D">0</span>]);
exit(<span style="color:#00D">1</span>);
}
cert_name = argv[<span style="color:#00D">1</span>];
pin = argv[<span style="color:#00D">2</span>];
PK11_SetPasswordFunc(passwdcb);
NSS_InitializePRErrorTable();
rv = NSS_Init(<span style="background-color:hsla(0,100%,50%,0.05)"><span style="color:#710">&quot;</span><span style="color:#D20">.</span><span style="color:#710">&quot;</span></span>);
<span style="color:#080;font-weight:bold">if</span> (rv != SECSuccess) {
fprintf(stderr, <span style="background-color:hsla(0,100%,50%,0.05)"><span style="color:#710">&quot;</span><span style="color:#D20">NSS initialization failed (err %d)</span><span style="color:#b0b">\n</span><span style="color:#710">&quot;</span></span>, PR_GetError());
<span style="color:#080;font-weight:bold">goto</span> cleanup;
}
cert = PK11_FindCertFromNickname(cert_name, <span style="color:#069">NULL</span>);
<span style="color:#080;font-weight:bold">if</span> (cert == <span style="color:#069">NULL</span>) {
fprintf(stderr, <span style="background-color:hsla(0,100%,50%,0.05)"><span style="color:#710">&quot;</span><span style="color:#D20">Couldn't find cert %s in NSS db (err %d: %s)</span><span style="color:#b0b">\n</span><span style="color:#710">&quot;</span></span>,
cert_name, PR_GetError(), PORT_ErrorToString(PR_GetError()));
<span style="color:#080;font-weight:bold">goto</span> cleanup;
}
fprintf(stderr, <span style="background-color:hsla(0,100%,50%,0.05)"><span style="color:#710">&quot;</span><span style="color:#D20">Buffer being signed = </span><span style="color:#b0b">\n</span><span style="color:#D20">%s</span><span style="color:#b0b">\n</span><span style="color:#710">&quot;</span></span>, buf);
pvtkey = PK11_FindKeyByAnyCert(cert, <span style="color:#069">NULL</span>);
<span style="color:#080;font-weight:bold">if</span> (pvtkey == <span style="color:#069">NULL</span>) {
fprintf(stderr, <span style="background-color:hsla(0,100%,50%,0.05)"><span style="color:#710">&quot;</span><span style="color:#D20">Couldn't find private key for cert %s (err %d: %s)</span><span style="color:#b0b">\n</span><span style="color:#710">&quot;</span></span>,
cert_name, PR_GetError(), PORT_ErrorToString(PR_GetError()));
<span style="color:#080;font-weight:bold">goto</span> cleanup;
}
<span style="color:#777">/* get the algtag. Pick the default hash algorithm */</span>
algTag = SEC_GetSignatureAlgorithmOidTag(pvtkey-&gt;keyType, SEC_OID_UNKNOWN);
fprintf(stderr, <span style="background-color:hsla(0,100%,50%,0.05)"><span style="color:#710">&quot;</span><span style="color:#D20">Signing with alg = %s (%d)</span><span style="color:#b0b">\n</span><span style="color:#710">&quot;</span></span>,
SECOID_FindOIDTagDescription(algTag), algTag);
rv = SEC_SignData(&amp;signature, buf, <span style="color:#080;font-weight:bold">sizeof</span>(buf)-<span style="color:#00D">1</span>, pvtkey, algTag);
<span style="color:#080;font-weight:bold">if</span> (rv != SECSuccess) {
fprintf(stderr, <span style="background-color:hsla(0,100%,50%,0.05)"><span style="color:#710">&quot;</span><span style="color:#D20">sign with Private Key failed (err %d: %s)</span><span style="color:#b0b">\n</span><span style="color:#710">&quot;</span></span>,
PR_GetError(), PORT_ErrorToString(PR_GetError()));
<span style="color:#080;font-weight:bold">goto</span> cleanup;
}</code></pre>
</div>
</div>
</div>
</div>
<div class="paragraph">
<p>To use the example above with an HSM or smart card you will need to do the following.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code data-lang="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 &quot;My HSM&quot; -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 &quot;${token_name}:${cert_name}&quot;</code></pre>
</div>
</div>
<div id="ex-Defensive_Coding-HSM-NSS-PIN" class="exampleblock">
<div class="title">Example 5. An example PIN callback with NSS</div>
<div class="content">
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code data-lang="c"><span style="color:#0a8;font-weight:bold">char</span> *passwdcb(PK11SlotInfo * slot, PRBool retry, <span style="color:#088;font-weight:bold">void</span> *arg)
{
<span style="color:#080;font-weight:bold">if</span> (!isatty(STDIN_FILENO) &amp;&amp; retry) {
<span style="color:#777">/* 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. */</span>
<span style="color:#080;font-weight:bold">return</span> <span style="color:#069">NULL</span>;
}
<span style="color:#080;font-weight:bold">if</span> (retry) {
printf(<span style="background-color:hsla(0,100%,50%,0.05)"><span style="color:#710">&quot;</span><span style="color:#D20">Warning: Wrong PIN has been provided in the previous attempt</span><span style="color:#b0b">\n</span><span style="color:#710">&quot;</span></span>);
<span style="color:#080;font-weight:bold">if</span> (PK11_IsHW(slot)) {
printf
(<span style="background-color:hsla(0,100%,50%,0.05)"><span style="color:#710">&quot;</span><span style="color:#D20"> NOTE: multiple pin failures could result in locking your device</span><span style="color:#b0b">\n</span><span style="color:#710">&quot;</span></span>);
}
}
<span style="color:#080;font-weight:bold">if</span> (pin == <span style="color:#069">NULL</span>)
<span style="color:#080;font-weight:bold">return</span> pin;
<span style="color:#080;font-weight:bold">else</span>
<span style="color:#080;font-weight:bold">return</span> strdup(pin);
}</code></pre>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<div id="bottom" class="text-muted py-3" >
<div class="foot">
<div class="container">
<div class="row footerlinks">
<div class="col-sm-3 col-xs-6 widget">
<h3 class="widget-title">About</h3>
<div class="widget-body">
<dl>
<dd><a href="https://fedoraproject.org/wiki/Overview">About Fedora</a></dd>
<dd><a href="https://getfedora.org/en/sponsors">Sponsors</a></dd>
<dd><a href="https://fedoramagazine.org">Fedora Magazine</a></dd>
<dd><a href="https://fedoraproject.org/wiki/Legal:Main#Legal">Legal</a></dd>
</dl>
<ul class="list-inline">
<li>
<a href="https://www.facebook.com/TheFedoraProject" class="btn-social btn-outline"><i class="fa fa-fw fa-facebook"></i></a>
</li>
<li>
<a href="https://plus.google.com/112917221531140868607" class="btn-social btn-outline"><i class="fa fa-fw fa-google-plus"></i></a>
</li>
<li>
<a href="https://twitter.com/fedora" class="btn-social btn-outline"><i class="fa fa-fw fa-twitter"></i></a>
</li>
</ul>
</div>
</div>
<div class="col-sm-3 col-xs-6 widget">
<h3 class="widget-title uppercase">Download</h3>
<div class="widget-body">
<dl>
<dd><a href="https://getfedora.org/en/workstation/download">Get Fedora Workstation</a></dd>
<dd><a href="https://getfedora.org/en/server/download">Get Fedora Server</a></dd>
<dd><a href="https://getfedora.org/en/atomic/download">Get Fedora Atomic</a></dd>
<dd><a href="https://spins.fedoraproject.org">Fedora Spins</a></dd>
<dd><a href="https://labs.fedoraproject.org">Fedora Labs</a></dd>
<dd><a href="https://arm.fedoraproject.org">Fedora ARM<span class="sup">&reg;</span></a></dd>
<dd><a href="https://alt.fedoraproject.org/">Alternative Downloads</a></dd>
</dl>
</div>
</div>
<div class="col-sm-3 col-xs-6 widget">
<h3 class="widget-title">Support</h3>
<div class="widget-body">
<dl>
<dd><a href="https://fedoraproject.org/wiki/Communicating_and_getting_help">Get Help</a></dd>
<dd><a href="https://ask.fedoraproject.org/">Ask Fedora</a></dd>
<dd><a href="https://fedoraproject.org/wiki/Common_F27_bugs">Common Bugs</a></dd>
<dd><a href="https://developer.fedoraproject.org/">Fedora Developer Portal</a></dd>
<dd><a href="https://docs.fedoraproject.org/f27/install-guide/index.html">Installation Guide</a></dd>
</dl>
</div>
</div>
<div class="col-sm-3 col-xs-6 widget">
<h3 class="widget-title">Join</h3>
<div class="widget-body">
<dl>
<dd><a href="https://fedoraproject.org/wiki/Join">Join Fedora</a></dd>
<dd><a href="http://fedoraplanet.org">Planet Fedora</a></dd>
<dd><a href="https://fedoraproject.org/wiki/SIGs">Fedora SIGs</a></dd>
<dd><a href="https://admin.fedoraproject.org/accounts/">Fedora Account System</a></dd>
<dd><a href="https://fedoracommunity.org/">Fedora Community</a></dd>
</dl>
</div>
</div>
</div> <!-- /row of widgets -->
<div class="row">
<div class="col-md-2">
<div class="widget-body">
<a href="https://www.redhat.com/"><img class="rh-logo" src="../../../master/_images/redhat-logo.png" alt="Red Hat Logo" /></a>
</div>
</div>
<div class="col-md-7">
<div class="widget-body">
<p class="sponsor">Fedora is sponsored by Red Hat.</p>
<p class="sponsor"><a href="https://www.redhat.com/en/technologies/linux-platforms/articles/relationship-between-fedora-and-rhel">Learn more about the relationship between Red Hat and Fedora &raquo;</a></p>
<p class="copy">&copy; 2017 Red Hat, Inc. and others. Please send any comments or corrections to the <a href="https://pagure.io/fedora-docs/docs-fp-o">documentation team</a></p>
</div>
</div>
</div> <!-- /row of widgets -->
</div>
</div>
</div>
<!-- jQuery (necessary for Bootstrap's JavaScript plugins) -->
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>
<!-- Latest compiled and minified JavaScript -->
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/js/bootstrap.min.js"></script>
<script src="../../../master/_javascripts/bootstrap-offcanvas.js" type="text/javascript"></script>
<script type="text/javascript">
/*<![CDATA[*/
$(document).ready(function() {
$("[id^='topicGroup']").on('show.bs.collapse', function (event) {
if (!($(event.target).attr('id').match(/^topicSubGroup/))) {
$(this).parent().find("[id^='tgSpan']").toggleClass("fa-angle-right fa-angle-down");
}
});
$("[id^='topicGroup']").on('hide.bs.collapse', function (event) {
if (!($(event.target).attr('id').match(/^topicSubGroup/))) {
$(this).parent().find("[id^='tgSpan']").toggleClass("fa-angle-right fa-angle-down");
}
});
$("[id^='topicSubGroup']").on('show.bs.collapse', function () {
$(this).parent().find("[id^='sgSpan']").toggleClass("fa-caret-right fa-caret-down");
});
$("[id^='topicSubGroup']").on('hide.bs.collapse', function () {
$(this).parent().find("[id^='sgSpan']").toggleClass("fa-caret-right fa-caret-down");
});
});
/*]]>*/
</script>
</body>
</html>

File diff suppressed because it is too large Load diff

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load diff

View file

@ -1,641 +0,0 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta content="IE=edge" http-equiv="X-UA-Compatible">
<meta content="width=device-width, initial-scale=1.0" name="viewport">
<title>Defensive Coding Guide | Defensive Coding Guide | Programming Languages | The C++ Programming&nbsp;Language</title>
<!-- Bootstrap -->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css">
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap-theme.min.css">
<!-- Overpass Font -->
<link rel="stylesheet" href="https://overpass-30e2.kxcdn.com/overpass.css">
<link href="../../../master/_stylesheets/asciibinder.css" rel="stylesheet" />
<!-- HTML5 shim and Respond.js for IE8 support of HTML5 elements and media queries -->
<!-- WARNING: Respond.js doesn't work if you view the page via file:// -->
<!--[if lt IE 9]>
<script src="https://oss.maxcdn.com/html5shiv/3.7.2/html5shiv.min.js"></script>
<script src="https://oss.maxcdn.com/respond/1.4.2/respond.min.js"></script>
<![endif]-->
<link href="../../../master/_images/favicon32x32.png" rel="shortcut icon" type="text/css">
<!--[if IE]><link rel="shortcut icon" href="../../../master/_images/favicon.ico"><![endif]-->
<meta content="AsciiBinder" name="application-name">
</head>
<body>
<div class="navbar navbar-default" role="navigation">
<div class="container-fluid">
<div class="navbar-header">
<a class="navbar-brand" href="https://docs.fedoraproject.org/"><img alt="Fedora Documentation" src="../../../master/_images/fedora.svg"></a>
</div>
</div>
</div>
<div class="container">
<p class="toggle-nav visible-xs pull-left">
<button class="btn btn-default btn-sm" type="button" data-toggle="offcanvas">Toggle nav</button>
</p>
<ol class="breadcrumb">
<li class="sitename">
<a href="../../../index.html">Home</a>
</li>
<li class="hidden-xs active">
<a href="../../en-US/index.html">Defensive Coding Guide </a>
</li>
<li class="hidden-xs active">
<a href="../../en-US/index.html">Defensive Coding Guide</a>
</li>
<li class="hidden-xs active"><a href="../../en-US/programming-languages/C.html">Programming Languages</a></li>
<li class="hidden-xs active">
The C++ Programming&nbsp;Language
</li>
</ol>
<div class="row row-offcanvas row-offcanvas-left">
<div class="col-xs-8 col-sm-3 col-md-3 sidebar sidebar-offcanvas">
<ul class="nav nav-sidebar">
<li class="nav-header">
<a class="" href="#" data-toggle="collapse" data-target="#topicGroup0">
<span id="tgSpan0" class="fa fa-angle-down"></span>Defensive Coding Guide
</a>
<ul id="topicGroup0" class="collapse in list-unstyled">
<li><a class="" href="../../en-US/index.html">Book Information</a></li>
<li class="nav-header">
<a class="" href="#" data-toggle="collapse" data-target="#topicSubGroup-0-1">
<span id="sgSpan-0-1" class="fa fa-caret-down"></span>&nbsp;Programming Languages
</a>
<ul id="topicSubGroup-0-1" class="nav-tertiary list-unstyled collapse in">
<li><a class="" href="../../en-US/programming-languages/C.html">The C Programming Language</a></li>
<li><a class=" active" href="../../en-US/programming-languages/CXX.html">The C++ Programming&nbsp;Language</a></li>
<li><a class="" href="../../en-US/programming-languages/Java.html">The Java Programming Language</a></li>
<li><a class="" href="../../en-US/programming-languages/Python.html">The Python Programming Language</a></li>
<li><a class="" href="../../en-US/programming-languages/Shell.html">Shell Programming and bash</a></li>
<li><a class="" href="../../en-US/programming-languages/Go.html">The Go Programming Language</a></li>
<li><a class="" href="../../en-US/programming-languages/Vala.html">The Vala Programming Language</a></li>
</ul>
</li>
<li class="nav-header">
<a class="" href="#" data-toggle="collapse" data-target="#topicSubGroup-0-2">
<span id="sgSpan-0-2" class="fa fa-caret-right"></span>&nbsp;Specific Programming Tasks
</a>
<ul id="topicSubGroup-0-2" class="nav-tertiary list-unstyled collapse">
<li><a class="" href="../../en-US/tasks/Tasks-Library_Design.html">Library Design</a></li>
<li><a class="" href="../../en-US/tasks/Tasks-Descriptors.html">File Descriptor Management</a></li>
<li><a class="" href="../../en-US/tasks/Tasks-File_System.html">File System Manipulation</a></li>
<li><a class="" href="../../en-US/tasks/Tasks-Temporary_Files.html">Temporary Files</a></li>
<li><a class="" href="../../en-US/tasks/Tasks-Processes.html">Processes</a></li>
<li><a class="" href="../../en-US/tasks/Tasks-Serialization.html">Serialization and Deserialization</a></li>
<li><a class="" href="../../en-US/tasks/Tasks-Cryptography.html">Cryptography</a></li>
<li><a class="" href="../../en-US/tasks/Tasks-Packaging.html">RPM Packaging</a></li>
</ul>
</li>
<li class="nav-header">
<a class="" href="#" data-toggle="collapse" data-target="#topicSubGroup-0-3">
<span id="sgSpan-0-3" class="fa fa-caret-right"></span>&nbsp;Implementing Security Features
</a>
<ul id="topicSubGroup-0-3" class="nav-tertiary list-unstyled collapse">
<li><a class="" href="../../en-US/features/Features-Authentication.html">Authentication and Authorization</a></li>
<li><a class="" href="../../en-US/features/Features-TLS.html">Transport Layer Security (TLS)</a></li>
<li><a class="" href="../../en-US/features/Features-HSM.html">Hardware Security Modules and Smart Cards</a></li>
</ul>
</li>
<li><a class="" href="../../en-US/Revision_History.html">Revision History</a></li>
</ul>
</li>
</ul>
</div>
<div class="col-xs-12 col-sm-9 col-md-9 main">
<div class="page-header">
<h2>The C++ Programming Language</h2>
</div>
<div class="sect1">
<h2 id="sect-Defensive_Coding-CXX-Language"><a class="anchor" href="#sect-Defensive_Coding-CXX-Language"></a>The Core Language</h2>
<div class="sectionbody">
<div class="paragraph">
<p>C++ includes a large subset of the C language. As far as the C
subset is used, the recommendations in <a href="#chap-Defensive_Coding-C">[chap-Defensive_Coding-C]</a> apply.</p>
</div>
<div class="sect2">
<h3 id="array-allocation-with-code-operator-new-code"><a class="anchor" href="#array-allocation-with-code-operator-new-code"></a>Array Allocation with <code>operator new[]</code></h3>
<div class="paragraph">
<p>For very large values of <code>n</code>, an expression
like <code>new T[n]</code> 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 <code>sizeof(T) * size_t(n)<br>
cookie_size</code>, where <code>cookie_size</code> 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.)</p>
</div>
<div class="paragraph">
<p>The <code>std::vector</code> template can be used instead
an explicit array allocation. (The GCC implementation detects
overflow internally.)</p>
</div>
<div class="paragraph">
<p>If there is no alternative to <code>operator new[]</code>
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 <code>new T[n]</code> example,
the size check could be <code>n || (n &gt; 0 &amp;&amp; n &gt;
(size_t(-1) - 8) / sizeof(T))</code>. (See <a href="#sect-Defensive_Coding-C-Arithmetic">[sect-Defensive_Coding-C-Arithmetic]</a>.) If there are
additional dimensions (which must be constants according to the
C++ standard), these should be included as factors in the
divisor.</p>
</div>
<div class="paragraph">
<p>These countermeasures prevent out-of-bounds writes and potential
code execution. Very large memory allocations can still lead to
a denial of service. <a href="#sect-Defensive_Coding-Tasks-Serialization-Decoders">[sect-Defensive_Coding-Tasks-Serialization-Decoders]</a>
contains suggestions for mitigating this problem when processing
untrusted data.</p>
</div>
<div class="paragraph">
<p>See <a href="#sect-Defensive_Coding-C-Allocators-Arrays">[sect-Defensive_Coding-C-Allocators-Arrays]</a>
for array allocation advice for C-style memory allocation.</p>
</div>
</div>
<div class="sect2">
<h3 id="overloading"><a class="anchor" href="#overloading"></a>Overloading</h3>
<div class="paragraph">
<p>Do not overload functions with versions that have different
security characteristics. For instance, do not implement a
function <code>strcat</code> which works on
<code>std::string</code> arguments. Similarly, do not name
methods after such functions.</p>
</div>
</div>
<div class="sect2">
<h3 id="abi-compatibility-and-preparing-for-security-updates"><a class="anchor" href="#abi-compatibility-and-preparing-for-security-updates"></a>ABI compatibility and preparing for security updates</h3>
<div class="paragraph">
<p>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.</p>
</div>
<div class="paragraph">
<p>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:</p>
</div>
<div class="ulist">
<ul>
<li>
<p>Avoid inline functions.</p>
</li>
<li>
<p>Use the pointer-to-implementation idiom.</p>
</li>
<li>
<p>Try to avoid templates. Use them if the increased type
safety provides a benefit to the programmer.</p>
</li>
<li>
<p>Move security-critical code out of templated code, so that
it can be patched in a central place if necessary.</p>
</li>
</ul>
</div>
<div class="paragraph">
<p>The KDE project publishes a document with more extensive
guidelines on ABI-preserving changes to C++ code, <a href="https://community.kde.org/Policies/Binary_Compatibility_Issues_With_C%2B%2B">Policies/Binary
Compatibility Issues With C++</a>
(<strong>d-pointer</strong> refers to the
pointer-to-implementation idiom).</p>
</div>
</div>
<div class="sect2">
<h3 id="sect-Defensive_Coding-CXX-Language-CXX11"><a class="anchor" href="#sect-Defensive_Coding-CXX-Language-CXX11"></a>C++0X and C++11 Support</h3>
<div class="paragraph">
<p>GCC offers different language compatibility modes:</p>
</div>
<div class="ulist">
<ul>
<li>
<p><code class="option">-std=c++98</code> for the original 1998 C++
standard</p>
</li>
<li>
<p><code class="option">-std=c++03</code> for the 1998 standard with the
changes from the TR1 technical report</p>
</li>
<li>
<p><code class="option">-std=c++11</code> for the 2011 C++ standard. This
option should not be used.</p>
</li>
<li>
<p><code class="option">-std=c++0x</code> for several different versions
of C++11 support in development, depending on the GCC
version. This option should not be used.</p>
</li>
</ul>
</div>
<div class="paragraph">
<p>For each of these flags, there are variants which also enable
GNU extensions (mostly language features also found in C99 or
C11):</p>
</div>
<div class="ulist">
<ul>
<li>
<p><code class="option">-std=gnu++98</code></p>
</li>
<li>
<p><code class="option">-std=gnu++03</code></p>
</li>
<li>
<p><code class="option">-std=gnu++11</code></p>
</li>
</ul>
</div>
<div class="paragraph">
<p>Again, <code class="option">-std=gnu++11</code> should not be used.</p>
</div>
<div class="paragraph">
<p>If you enable C++11 support, the ABI of the standard C++ library
<code>libstdc++</code> 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).</p>
</div>
<div class="paragraph">
<p>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.</p>
</div>
<div class="paragraph">
<p>Some C++11 features (or approximations thereof) are available
with TR1 support, that is, with <code class="option">-std=c03` or
[option]`-std=gnu03</code> and in the
<code>&lt;tr1/*&gt;</code> header files. This includes
<code>std::tr1::shared_ptr</code> (from
<code>&lt;tr1/memory&gt;</code>) and
<code>std::tr1::function</code> (from
<code>&lt;tr1/functional&gt;</code>). For other C++11
features, the Boost C++ library contains replacements.</p>
</div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="sect-Defensive_Coding-CXX-Std"><a class="anchor" href="#sect-Defensive_Coding-CXX-Std"></a>The C++ Standard Library</h2>
<div class="sectionbody">
<div class="paragraph">
<p>The C++ standard library includes most of its C counterpart
by reference, see <a href="#sect-Defensive_Coding-C-Libc">[sect-Defensive_Coding-C-Libc]</a>.</p>
</div>
<div class="sect2">
<h3 id="sect-Defensive_Coding-CXX-Std-Functions"><a class="anchor" href="#sect-Defensive_Coding-CXX-Std-Functions"></a>Functions That Are Difficult to Use</h3>
<div class="paragraph">
<p>This section collects functions and function templates which are
part of the standard library and are difficult to use.</p>
</div>
<div class="sect3">
<h4 id="sect-Defensive_Coding-CXX-Std-Functions-Unpaired_Iterators"><a class="anchor" href="#sect-Defensive_Coding-CXX-Std-Functions-Unpaired_Iterators"></a>Unpaired Iterators</h4>
<div class="paragraph">
<p>Functions which use output operators or iterators which do not
come in pairs (denoting ranges) cannot perform iterator range
checking.
(See <a href="#sect-Defensive_Coding-CXX-Std-Iterators">Iterators</a>)
Function templates which involve output iterators are
particularly dangerous:</p>
</div>
<div class="ulist">
<ul>
<li>
<p><code>std::copy</code></p>
</li>
<li>
<p><code>std::copy_backward</code></p>
</li>
<li>
<p><code>std::copy_if</code></p>
</li>
<li>
<p><code>std::move</code> (three-argument variant)</p>
</li>
<li>
<p><code>std::move_backward</code></p>
</li>
<li>
<p><code>std::partition_copy_if</code></p>
</li>
<li>
<p><code>std::remove_copy</code></p>
</li>
<li>
<p><code>std::remove_copy_if</code></p>
</li>
<li>
<p><code>std::replace_copy</code></p>
</li>
<li>
<p><code>std::replace_copy_if</code></p>
</li>
<li>
<p><code>std::swap_ranges</code></p>
</li>
<li>
<p><code>std::transform</code></p>
</li>
</ul>
</div>
<div class="paragraph">
<p>In addition, <code>std::copy_n</code>,
<code>std::fill_n</code> and
<code>std::generate_n</code> 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.</p>
</div>
<div class="paragraph">
<p>These output-iterator-expecting functions should only be used
with unlimited-range output iterators, such as iterators
obtained with the <code>std::back_inserter</code>
function.</p>
</div>
<div class="paragraph">
<p>Other functions use single input or forward iterators, which can
read beyond the end of the input range if the caller is not careful:</p>
</div>
<div class="ulist">
<ul>
<li>
<p><code>std::equal</code></p>
</li>
<li>
<p><code>std::is_permutation</code></p>
</li>
<li>
<p><code>std::mismatch</code></p>
</li>
</ul>
</div>
</div>
</div>
<div class="sect2">
<h3 id="sect-Defensive_Coding-CXX-Std-String"><a class="anchor" href="#sect-Defensive_Coding-CXX-Std-String"></a>String Handling with <code>std::string</code></h3>
<div class="paragraph">
<p>The <code>std::string</code> class provides a convenient
way to handle strings. Unlike C strings,
<code>std::string</code> objects have an explicit length
(and can contain embedded NUL characters), and storage for its
characters is managed automatically. This section discusses
<code>std::string</code>, but these observations also
apply to other instances of the
<code>std::basic_string</code> template.</p>
</div>
<div class="paragraph">
<p>The pointer returned by the <code>data()</code> member
function does not necessarily point to a NUL-terminated string.
To obtain a C-compatible string pointer, use
<code>c_str()</code> instead, which adds the NUL
terminator.</p>
</div>
<div class="paragraph">
<p>The pointers returned by the <code>data()</code> and
<code>c_str()</code> functions and iterators are only
valid until certain events happen. It is required that the
exact <code>std::string</code> 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
<code>begin()</code>, in violation of the C++ standard.</p>
</div>
<div class="paragraph">
<p>Particular care is necessary when invoking the
<code>c_str()</code> 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 <code>c_str()</code>
is called completes evaluation. Passing the result of
<code>c_str()</code> to a function which does not store
or otherwise leak that pointer is safe, though.</p>
</div>
<div class="paragraph">
<p>Like with <code>std::vector</code> and
<code>std::array</code>, subscribing with
<code>operator[]</code> does not perform bounds checks.
Use the <code>at(size_type)</code> member function
instead. See <a href="#sect-Defensive_Coding-CXX-Std-Subscript">Containers and <code>operator[]</code></a>.
Furthermore, accessing the terminating NUL character using
<code>operator[]</code> is not possible. (In some
implementations, the <code>c_str()</code> member function
writes the NUL character on demand.)</p>
</div>
<div class="paragraph">
<p>Never write to the pointers returned by
<code>data()</code> or <code>c_str()</code>
after casting away <code>const</code>. If you need a
C-style writable string, use a
<code>std::vector&lt;char&gt;</code> object and its
<code>data()</code> member function. In this case, you
have to explicitly add the terminating NUL character.</p>
</div>
<div class="paragraph">
<p>GCC&#8217;s implementation of <code>std::string</code> 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.</p>
</div>
</div>
<div class="sect2">
<h3 id="sect-Defensive_Coding-CXX-Std-Subscript"><a class="anchor" href="#sect-Defensive_Coding-CXX-Std-Subscript"></a>Containers and <code>operator[]</code></h3>
<div class="paragraph">
<p>Many sequence containers similar to <code>std::vector</code>
provide both <code>operator[](size_type)</code> and a
member function <code>at(size_type)</code>. This applies
to <code>std::vector</code> itself,
<code>std::array</code>, <code>std::string</code>
and other instances of <code>std::basic_string</code>.</p>
</div>
<div class="paragraph">
<p><code>operator[](size_type)</code> is not required by the
standard to perform bounds checking (and the implementation in
GCC does not). In contrast, <code>at(size_type)</code>
must perform such a check. Therefore, in code which is not
performance-critical, you should prefer
<code>at(size_type)</code> over
<code>operator[](size_type)</code>, even though it is
slightly more verbose.</p>
</div>
<div class="paragraph">
<p>The <code>front()</code> and <code>back()</code>
member functions are undefined if a vector object is empty. You
can use <code>vec.at(0)</code> and
<code>vec.at(vec.size() - 1)</code> as checked
replacements. For an empty vector, <code>data()</code> is
defined; it returns an arbitrary pointer, but not necessarily
the NULL pointer.</p>
</div>
</div>
<div class="sect2">
<h3 id="sect-Defensive_Coding-CXX-Std-Iterators"><a class="anchor" href="#sect-Defensive_Coding-CXX-Std-Iterators"></a>Iterators</h3>
<div class="paragraph">
<p>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.</p>
</div>
<div class="paragraph">
<p>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.</p>
</div>
<div class="paragraph">
<p>These issues make some of the standard library functions
difficult to use correctly, see <a href="#sect-Defensive_Coding-CXX-Std-Functions-Unpaired_Iterators">Unpaired Iterators</a>.</p>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<div id="bottom" class="text-muted py-3" >
<div class="foot">
<div class="container">
<div class="row footerlinks">
<div class="col-sm-3 col-xs-6 widget">
<h3 class="widget-title">About</h3>
<div class="widget-body">
<dl>
<dd><a href="https://fedoraproject.org/wiki/Overview">About Fedora</a></dd>
<dd><a href="https://getfedora.org/en/sponsors">Sponsors</a></dd>
<dd><a href="https://fedoramagazine.org">Fedora Magazine</a></dd>
<dd><a href="https://fedoraproject.org/wiki/Legal:Main#Legal">Legal</a></dd>
</dl>
<ul class="list-inline">
<li>
<a href="https://www.facebook.com/TheFedoraProject" class="btn-social btn-outline"><i class="fa fa-fw fa-facebook"></i></a>
</li>
<li>
<a href="https://plus.google.com/112917221531140868607" class="btn-social btn-outline"><i class="fa fa-fw fa-google-plus"></i></a>
</li>
<li>
<a href="https://twitter.com/fedora" class="btn-social btn-outline"><i class="fa fa-fw fa-twitter"></i></a>
</li>
</ul>
</div>
</div>
<div class="col-sm-3 col-xs-6 widget">
<h3 class="widget-title uppercase">Download</h3>
<div class="widget-body">
<dl>
<dd><a href="https://getfedora.org/en/workstation/download">Get Fedora Workstation</a></dd>
<dd><a href="https://getfedora.org/en/server/download">Get Fedora Server</a></dd>
<dd><a href="https://getfedora.org/en/atomic/download">Get Fedora Atomic</a></dd>
<dd><a href="https://spins.fedoraproject.org">Fedora Spins</a></dd>
<dd><a href="https://labs.fedoraproject.org">Fedora Labs</a></dd>
<dd><a href="https://arm.fedoraproject.org">Fedora ARM<span class="sup">&reg;</span></a></dd>
<dd><a href="https://alt.fedoraproject.org/">Alternative Downloads</a></dd>
</dl>
</div>
</div>
<div class="col-sm-3 col-xs-6 widget">
<h3 class="widget-title">Support</h3>
<div class="widget-body">
<dl>
<dd><a href="https://fedoraproject.org/wiki/Communicating_and_getting_help">Get Help</a></dd>
<dd><a href="https://ask.fedoraproject.org/">Ask Fedora</a></dd>
<dd><a href="https://fedoraproject.org/wiki/Common_F27_bugs">Common Bugs</a></dd>
<dd><a href="https://developer.fedoraproject.org/">Fedora Developer Portal</a></dd>
<dd><a href="https://docs.fedoraproject.org/f27/install-guide/index.html">Installation Guide</a></dd>
</dl>
</div>
</div>
<div class="col-sm-3 col-xs-6 widget">
<h3 class="widget-title">Join</h3>
<div class="widget-body">
<dl>
<dd><a href="https://fedoraproject.org/wiki/Join">Join Fedora</a></dd>
<dd><a href="http://fedoraplanet.org">Planet Fedora</a></dd>
<dd><a href="https://fedoraproject.org/wiki/SIGs">Fedora SIGs</a></dd>
<dd><a href="https://admin.fedoraproject.org/accounts/">Fedora Account System</a></dd>
<dd><a href="https://fedoracommunity.org/">Fedora Community</a></dd>
</dl>
</div>
</div>
</div> <!-- /row of widgets -->
<div class="row">
<div class="col-md-2">
<div class="widget-body">
<a href="https://www.redhat.com/"><img class="rh-logo" src="../../../master/_images/redhat-logo.png" alt="Red Hat Logo" /></a>
</div>
</div>
<div class="col-md-7">
<div class="widget-body">
<p class="sponsor">Fedora is sponsored by Red Hat.</p>
<p class="sponsor"><a href="https://www.redhat.com/en/technologies/linux-platforms/articles/relationship-between-fedora-and-rhel">Learn more about the relationship between Red Hat and Fedora &raquo;</a></p>
<p class="copy">&copy; 2017 Red Hat, Inc. and others. Please send any comments or corrections to the <a href="https://pagure.io/fedora-docs/docs-fp-o">documentation team</a></p>
</div>
</div>
</div> <!-- /row of widgets -->
</div>
</div>
</div>
<!-- jQuery (necessary for Bootstrap's JavaScript plugins) -->
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>
<!-- Latest compiled and minified JavaScript -->
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/js/bootstrap.min.js"></script>
<script src="../../../master/_javascripts/bootstrap-offcanvas.js" type="text/javascript"></script>
<script type="text/javascript">
/*<![CDATA[*/
$(document).ready(function() {
$("[id^='topicGroup']").on('show.bs.collapse', function (event) {
if (!($(event.target).attr('id').match(/^topicSubGroup/))) {
$(this).parent().find("[id^='tgSpan']").toggleClass("fa-angle-right fa-angle-down");
}
});
$("[id^='topicGroup']").on('hide.bs.collapse', function (event) {
if (!($(event.target).attr('id').match(/^topicSubGroup/))) {
$(this).parent().find("[id^='tgSpan']").toggleClass("fa-angle-right fa-angle-down");
}
});
$("[id^='topicSubGroup']").on('show.bs.collapse', function () {
$(this).parent().find("[id^='sgSpan']").toggleClass("fa-caret-right fa-caret-down");
});
$("[id^='topicSubGroup']").on('hide.bs.collapse', function () {
$(this).parent().find("[id^='sgSpan']").toggleClass("fa-caret-right fa-caret-down");
});
});
/*]]>*/
</script>
</body>
</html>

View file

@ -1,356 +0,0 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta content="IE=edge" http-equiv="X-UA-Compatible">
<meta content="width=device-width, initial-scale=1.0" name="viewport">
<title>Defensive Coding Guide | Defensive Coding Guide | Programming Languages | The Go Programming Language</title>
<!-- Bootstrap -->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css">
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap-theme.min.css">
<!-- Overpass Font -->
<link rel="stylesheet" href="https://overpass-30e2.kxcdn.com/overpass.css">
<link href="../../../master/_stylesheets/asciibinder.css" rel="stylesheet" />
<!-- HTML5 shim and Respond.js for IE8 support of HTML5 elements and media queries -->
<!-- WARNING: Respond.js doesn't work if you view the page via file:// -->
<!--[if lt IE 9]>
<script src="https://oss.maxcdn.com/html5shiv/3.7.2/html5shiv.min.js"></script>
<script src="https://oss.maxcdn.com/respond/1.4.2/respond.min.js"></script>
<![endif]-->
<link href="../../../master/_images/favicon32x32.png" rel="shortcut icon" type="text/css">
<!--[if IE]><link rel="shortcut icon" href="../../../master/_images/favicon.ico"><![endif]-->
<meta content="AsciiBinder" name="application-name">
</head>
<body>
<div class="navbar navbar-default" role="navigation">
<div class="container-fluid">
<div class="navbar-header">
<a class="navbar-brand" href="https://docs.fedoraproject.org/"><img alt="Fedora Documentation" src="../../../master/_images/fedora.svg"></a>
</div>
</div>
</div>
<div class="container">
<p class="toggle-nav visible-xs pull-left">
<button class="btn btn-default btn-sm" type="button" data-toggle="offcanvas">Toggle nav</button>
</p>
<ol class="breadcrumb">
<li class="sitename">
<a href="../../../index.html">Home</a>
</li>
<li class="hidden-xs active">
<a href="../../en-US/index.html">Defensive Coding Guide </a>
</li>
<li class="hidden-xs active">
<a href="../../en-US/index.html">Defensive Coding Guide</a>
</li>
<li class="hidden-xs active"><a href="../../en-US/programming-languages/C.html">Programming Languages</a></li>
<li class="hidden-xs active">
The Go Programming Language
</li>
</ol>
<div class="row row-offcanvas row-offcanvas-left">
<div class="col-xs-8 col-sm-3 col-md-3 sidebar sidebar-offcanvas">
<ul class="nav nav-sidebar">
<li class="nav-header">
<a class="" href="#" data-toggle="collapse" data-target="#topicGroup0">
<span id="tgSpan0" class="fa fa-angle-down"></span>Defensive Coding Guide
</a>
<ul id="topicGroup0" class="collapse in list-unstyled">
<li><a class="" href="../../en-US/index.html">Book Information</a></li>
<li class="nav-header">
<a class="" href="#" data-toggle="collapse" data-target="#topicSubGroup-0-1">
<span id="sgSpan-0-1" class="fa fa-caret-down"></span>&nbsp;Programming Languages
</a>
<ul id="topicSubGroup-0-1" class="nav-tertiary list-unstyled collapse in">
<li><a class="" href="../../en-US/programming-languages/C.html">The C Programming Language</a></li>
<li><a class="" href="../../en-US/programming-languages/CXX.html">The C++ Programming&nbsp;Language</a></li>
<li><a class="" href="../../en-US/programming-languages/Java.html">The Java Programming Language</a></li>
<li><a class="" href="../../en-US/programming-languages/Python.html">The Python Programming Language</a></li>
<li><a class="" href="../../en-US/programming-languages/Shell.html">Shell Programming and bash</a></li>
<li><a class=" active" href="../../en-US/programming-languages/Go.html">The Go Programming Language</a></li>
<li><a class="" href="../../en-US/programming-languages/Vala.html">The Vala Programming Language</a></li>
</ul>
</li>
<li class="nav-header">
<a class="" href="#" data-toggle="collapse" data-target="#topicSubGroup-0-2">
<span id="sgSpan-0-2" class="fa fa-caret-right"></span>&nbsp;Specific Programming Tasks
</a>
<ul id="topicSubGroup-0-2" class="nav-tertiary list-unstyled collapse">
<li><a class="" href="../../en-US/tasks/Tasks-Library_Design.html">Library Design</a></li>
<li><a class="" href="../../en-US/tasks/Tasks-Descriptors.html">File Descriptor Management</a></li>
<li><a class="" href="../../en-US/tasks/Tasks-File_System.html">File System Manipulation</a></li>
<li><a class="" href="../../en-US/tasks/Tasks-Temporary_Files.html">Temporary Files</a></li>
<li><a class="" href="../../en-US/tasks/Tasks-Processes.html">Processes</a></li>
<li><a class="" href="../../en-US/tasks/Tasks-Serialization.html">Serialization and Deserialization</a></li>
<li><a class="" href="../../en-US/tasks/Tasks-Cryptography.html">Cryptography</a></li>
<li><a class="" href="../../en-US/tasks/Tasks-Packaging.html">RPM Packaging</a></li>
</ul>
</li>
<li class="nav-header">
<a class="" href="#" data-toggle="collapse" data-target="#topicSubGroup-0-3">
<span id="sgSpan-0-3" class="fa fa-caret-right"></span>&nbsp;Implementing Security Features
</a>
<ul id="topicSubGroup-0-3" class="nav-tertiary list-unstyled collapse">
<li><a class="" href="../../en-US/features/Features-Authentication.html">Authentication and Authorization</a></li>
<li><a class="" href="../../en-US/features/Features-TLS.html">Transport Layer Security (TLS)</a></li>
<li><a class="" href="../../en-US/features/Features-HSM.html">Hardware Security Modules and Smart Cards</a></li>
</ul>
</li>
<li><a class="" href="../../en-US/Revision_History.html">Revision History</a></li>
</ul>
</li>
</ul>
</div>
<div class="col-xs-12 col-sm-9 col-md-9 main">
<div class="page-header">
<h2>The Go Programming Language</h2>
</div>
<div id="preamble">
<div class="sectionbody">
<div class="paragraph">
<p>This chapter contains language-specific recommendations for Go.</p>
</div>
</div>
</div>
<div class="sect1">
<h2 id="chap-Defensive_Coding-Go-Memory_Safety"><a class="anchor" href="#chap-Defensive_Coding-Go-Memory_Safety"></a>Memory Safety</h2>
<div class="sectionbody">
<div class="paragraph">
<p>Go provides memory safety, but only if the program is not executed
in parallel (that is, <code>GOMAXPROCS</code> is not larger than
<code>1</code>). 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.</p>
</div>
<div class="paragraph">
<p>Code which does not run in parallel and does not use the
<code>unsafe</code> 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.</p>
</div>
<div class="paragraph">
<p>Keep in mind that finalization can introduce parallelism because
finalizers are executed concurrently, potentially interleaved with
the rest of the program.</p>
</div>
</div>
</div>
<div class="sect1">
<h2 id="chap-Defensive_Coding-Go-Error_Handling"><a class="anchor" href="#chap-Defensive_Coding-Go-Error_Handling"></a>Error Handling</h2>
<div class="sectionbody">
<div class="paragraph">
<p>Only a few common operations (such as pointer dereference, integer
division, array subscripting) trigger exceptions in Go, called
<strong>panics</strong>. Most interfaces in the standard
library use a separate return value of type
<code>error</code> to signal error.</p>
</div>
<div class="paragraph">
<p>Not checking error return values can lead to incorrect operation
and data loss (especially in the case of writes, using interfaces
such as <code>io.Writer</code>).</p>
</div>
<div class="paragraph">
<p>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 <code>nil</code> value, handling any encountered
error. See <a href="#ex-Defensive_Coding-Go-Error_Handling-Regular">Regular error handling in Go</a> for
details.</p>
</div>
<div id="ex-Defensive_Coding-Go-Error_Handling-Regular" class="exampleblock">
<div class="title">Example 1. Regular error handling in Go</div>
<div class="content">
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code data-lang="go">Unresolved directive in &lt;stdin&gt; - include::../snippets/Go-Error_Handling-Regular.adoc[]</code></pre>
</div>
</div>
</div>
</div>
<div class="paragraph">
<p>However, with <code>io.Reader</code>,
<code>io.ReaderAt</code> and related interfaces, it is
necessary to check for a non-zero number of read bytes first, as
shown in <a href="#ex-Defensive_Coding-Go-Error_Handling-IO">Read error handling in Go</a>. If this
pattern is not followed, data loss may occur. This is due to the
fact that the <code>io.Reader</code> interface permits
returning both data and an error at the same time.</p>
</div>
<div id="ex-Defensive_Coding-Go-Error_Handling-IO" class="exampleblock">
<div class="title">Example 2. Read error handling in Go</div>
<div class="content">
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code data-lang="go">Unresolved directive in &lt;stdin&gt; - include::../snippets/Go-Error_Handling-IO.adoc[]</code></pre>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="chap-Defensive_Coding-Go-Garbage_Collector"><a class="anchor" href="#chap-Defensive_Coding-Go-Garbage_Collector"></a>Garbage Collector</h2>
<div class="sectionbody">
<div class="paragraph">
<p>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.</p>
</div>
</div>
</div>
<div class="sect1">
<h2 id="chap-Defensive_Coding-Go-Marshaling"><a class="anchor" href="#chap-Defensive_Coding-Go-Marshaling"></a>Marshaling and Unmarshaling</h2>
<div class="sectionbody">
<div class="paragraph">
<p>Several packages in the <code>encoding</code> hierarchy
provide support for serialization and deserialization. The usual
caveats apply (see
<a href="#chap-Defensive_Coding-Tasks-Serialization">[chap-Defensive_Coding-Tasks-Serialization]</a>).</p>
</div>
<div class="paragraph">
<p>As an additional precaution, the <code>Unmarshal</code>
and <code>Decode</code> functions should only be used with
fresh values in the <code>interface{}</code> 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.</p>
</div>
</div>
</div>
</div>
</div>
</div>
<div id="bottom" class="text-muted py-3" >
<div class="foot">
<div class="container">
<div class="row footerlinks">
<div class="col-sm-3 col-xs-6 widget">
<h3 class="widget-title">About</h3>
<div class="widget-body">
<dl>
<dd><a href="https://fedoraproject.org/wiki/Overview">About Fedora</a></dd>
<dd><a href="https://getfedora.org/en/sponsors">Sponsors</a></dd>
<dd><a href="https://fedoramagazine.org">Fedora Magazine</a></dd>
<dd><a href="https://fedoraproject.org/wiki/Legal:Main#Legal">Legal</a></dd>
</dl>
<ul class="list-inline">
<li>
<a href="https://www.facebook.com/TheFedoraProject" class="btn-social btn-outline"><i class="fa fa-fw fa-facebook"></i></a>
</li>
<li>
<a href="https://plus.google.com/112917221531140868607" class="btn-social btn-outline"><i class="fa fa-fw fa-google-plus"></i></a>
</li>
<li>
<a href="https://twitter.com/fedora" class="btn-social btn-outline"><i class="fa fa-fw fa-twitter"></i></a>
</li>
</ul>
</div>
</div>
<div class="col-sm-3 col-xs-6 widget">
<h3 class="widget-title uppercase">Download</h3>
<div class="widget-body">
<dl>
<dd><a href="https://getfedora.org/en/workstation/download">Get Fedora Workstation</a></dd>
<dd><a href="https://getfedora.org/en/server/download">Get Fedora Server</a></dd>
<dd><a href="https://getfedora.org/en/atomic/download">Get Fedora Atomic</a></dd>
<dd><a href="https://spins.fedoraproject.org">Fedora Spins</a></dd>
<dd><a href="https://labs.fedoraproject.org">Fedora Labs</a></dd>
<dd><a href="https://arm.fedoraproject.org">Fedora ARM<span class="sup">&reg;</span></a></dd>
<dd><a href="https://alt.fedoraproject.org/">Alternative Downloads</a></dd>
</dl>
</div>
</div>
<div class="col-sm-3 col-xs-6 widget">
<h3 class="widget-title">Support</h3>
<div class="widget-body">
<dl>
<dd><a href="https://fedoraproject.org/wiki/Communicating_and_getting_help">Get Help</a></dd>
<dd><a href="https://ask.fedoraproject.org/">Ask Fedora</a></dd>
<dd><a href="https://fedoraproject.org/wiki/Common_F27_bugs">Common Bugs</a></dd>
<dd><a href="https://developer.fedoraproject.org/">Fedora Developer Portal</a></dd>
<dd><a href="https://docs.fedoraproject.org/f27/install-guide/index.html">Installation Guide</a></dd>
</dl>
</div>
</div>
<div class="col-sm-3 col-xs-6 widget">
<h3 class="widget-title">Join</h3>
<div class="widget-body">
<dl>
<dd><a href="https://fedoraproject.org/wiki/Join">Join Fedora</a></dd>
<dd><a href="http://fedoraplanet.org">Planet Fedora</a></dd>
<dd><a href="https://fedoraproject.org/wiki/SIGs">Fedora SIGs</a></dd>
<dd><a href="https://admin.fedoraproject.org/accounts/">Fedora Account System</a></dd>
<dd><a href="https://fedoracommunity.org/">Fedora Community</a></dd>
</dl>
</div>
</div>
</div> <!-- /row of widgets -->
<div class="row">
<div class="col-md-2">
<div class="widget-body">
<a href="https://www.redhat.com/"><img class="rh-logo" src="../../../master/_images/redhat-logo.png" alt="Red Hat Logo" /></a>
</div>
</div>
<div class="col-md-7">
<div class="widget-body">
<p class="sponsor">Fedora is sponsored by Red Hat.</p>
<p class="sponsor"><a href="https://www.redhat.com/en/technologies/linux-platforms/articles/relationship-between-fedora-and-rhel">Learn more about the relationship between Red Hat and Fedora &raquo;</a></p>
<p class="copy">&copy; 2017 Red Hat, Inc. and others. Please send any comments or corrections to the <a href="https://pagure.io/fedora-docs/docs-fp-o">documentation team</a></p>
</div>
</div>
</div> <!-- /row of widgets -->
</div>
</div>
</div>
<!-- jQuery (necessary for Bootstrap's JavaScript plugins) -->
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>
<!-- Latest compiled and minified JavaScript -->
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/js/bootstrap.min.js"></script>
<script src="../../../master/_javascripts/bootstrap-offcanvas.js" type="text/javascript"></script>
<script type="text/javascript">
/*<![CDATA[*/
$(document).ready(function() {
$("[id^='topicGroup']").on('show.bs.collapse', function (event) {
if (!($(event.target).attr('id').match(/^topicSubGroup/))) {
$(this).parent().find("[id^='tgSpan']").toggleClass("fa-angle-right fa-angle-down");
}
});
$("[id^='topicGroup']").on('hide.bs.collapse', function (event) {
if (!($(event.target).attr('id').match(/^topicSubGroup/))) {
$(this).parent().find("[id^='tgSpan']").toggleClass("fa-angle-right fa-angle-down");
}
});
$("[id^='topicSubGroup']").on('show.bs.collapse', function () {
$(this).parent().find("[id^='sgSpan']").toggleClass("fa-caret-right fa-caret-down");
});
$("[id^='topicSubGroup']").on('hide.bs.collapse', function () {
$(this).parent().find("[id^='sgSpan']").toggleClass("fa-caret-right fa-caret-down");
});
});
/*]]>*/
</script>
</body>
</html>

File diff suppressed because it is too large Load diff

View file

@ -1,313 +0,0 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta content="IE=edge" http-equiv="X-UA-Compatible">
<meta content="width=device-width, initial-scale=1.0" name="viewport">
<title>Defensive Coding Guide | Defensive Coding Guide | Programming Languages | The Python Programming Language</title>
<!-- Bootstrap -->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css">
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap-theme.min.css">
<!-- Overpass Font -->
<link rel="stylesheet" href="https://overpass-30e2.kxcdn.com/overpass.css">
<link href="../../../master/_stylesheets/asciibinder.css" rel="stylesheet" />
<!-- HTML5 shim and Respond.js for IE8 support of HTML5 elements and media queries -->
<!-- WARNING: Respond.js doesn't work if you view the page via file:// -->
<!--[if lt IE 9]>
<script src="https://oss.maxcdn.com/html5shiv/3.7.2/html5shiv.min.js"></script>
<script src="https://oss.maxcdn.com/respond/1.4.2/respond.min.js"></script>
<![endif]-->
<link href="../../../master/_images/favicon32x32.png" rel="shortcut icon" type="text/css">
<!--[if IE]><link rel="shortcut icon" href="../../../master/_images/favicon.ico"><![endif]-->
<meta content="AsciiBinder" name="application-name">
</head>
<body>
<div class="navbar navbar-default" role="navigation">
<div class="container-fluid">
<div class="navbar-header">
<a class="navbar-brand" href="https://docs.fedoraproject.org/"><img alt="Fedora Documentation" src="../../../master/_images/fedora.svg"></a>
</div>
</div>
</div>
<div class="container">
<p class="toggle-nav visible-xs pull-left">
<button class="btn btn-default btn-sm" type="button" data-toggle="offcanvas">Toggle nav</button>
</p>
<ol class="breadcrumb">
<li class="sitename">
<a href="../../../index.html">Home</a>
</li>
<li class="hidden-xs active">
<a href="../../en-US/index.html">Defensive Coding Guide </a>
</li>
<li class="hidden-xs active">
<a href="../../en-US/index.html">Defensive Coding Guide</a>
</li>
<li class="hidden-xs active"><a href="../../en-US/programming-languages/C.html">Programming Languages</a></li>
<li class="hidden-xs active">
The Python Programming Language
</li>
</ol>
<div class="row row-offcanvas row-offcanvas-left">
<div class="col-xs-8 col-sm-3 col-md-3 sidebar sidebar-offcanvas">
<ul class="nav nav-sidebar">
<li class="nav-header">
<a class="" href="#" data-toggle="collapse" data-target="#topicGroup0">
<span id="tgSpan0" class="fa fa-angle-down"></span>Defensive Coding Guide
</a>
<ul id="topicGroup0" class="collapse in list-unstyled">
<li><a class="" href="../../en-US/index.html">Book Information</a></li>
<li class="nav-header">
<a class="" href="#" data-toggle="collapse" data-target="#topicSubGroup-0-1">
<span id="sgSpan-0-1" class="fa fa-caret-down"></span>&nbsp;Programming Languages
</a>
<ul id="topicSubGroup-0-1" class="nav-tertiary list-unstyled collapse in">
<li><a class="" href="../../en-US/programming-languages/C.html">The C Programming Language</a></li>
<li><a class="" href="../../en-US/programming-languages/CXX.html">The C++ Programming&nbsp;Language</a></li>
<li><a class="" href="../../en-US/programming-languages/Java.html">The Java Programming Language</a></li>
<li><a class=" active" href="../../en-US/programming-languages/Python.html">The Python Programming Language</a></li>
<li><a class="" href="../../en-US/programming-languages/Shell.html">Shell Programming and bash</a></li>
<li><a class="" href="../../en-US/programming-languages/Go.html">The Go Programming Language</a></li>
<li><a class="" href="../../en-US/programming-languages/Vala.html">The Vala Programming Language</a></li>
</ul>
</li>
<li class="nav-header">
<a class="" href="#" data-toggle="collapse" data-target="#topicSubGroup-0-2">
<span id="sgSpan-0-2" class="fa fa-caret-right"></span>&nbsp;Specific Programming Tasks
</a>
<ul id="topicSubGroup-0-2" class="nav-tertiary list-unstyled collapse">
<li><a class="" href="../../en-US/tasks/Tasks-Library_Design.html">Library Design</a></li>
<li><a class="" href="../../en-US/tasks/Tasks-Descriptors.html">File Descriptor Management</a></li>
<li><a class="" href="../../en-US/tasks/Tasks-File_System.html">File System Manipulation</a></li>
<li><a class="" href="../../en-US/tasks/Tasks-Temporary_Files.html">Temporary Files</a></li>
<li><a class="" href="../../en-US/tasks/Tasks-Processes.html">Processes</a></li>
<li><a class="" href="../../en-US/tasks/Tasks-Serialization.html">Serialization and Deserialization</a></li>
<li><a class="" href="../../en-US/tasks/Tasks-Cryptography.html">Cryptography</a></li>
<li><a class="" href="../../en-US/tasks/Tasks-Packaging.html">RPM Packaging</a></li>
</ul>
</li>
<li class="nav-header">
<a class="" href="#" data-toggle="collapse" data-target="#topicSubGroup-0-3">
<span id="sgSpan-0-3" class="fa fa-caret-right"></span>&nbsp;Implementing Security Features
</a>
<ul id="topicSubGroup-0-3" class="nav-tertiary list-unstyled collapse">
<li><a class="" href="../../en-US/features/Features-Authentication.html">Authentication and Authorization</a></li>
<li><a class="" href="../../en-US/features/Features-TLS.html">Transport Layer Security (TLS)</a></li>
<li><a class="" href="../../en-US/features/Features-HSM.html">Hardware Security Modules and Smart Cards</a></li>
</ul>
</li>
<li><a class="" href="../../en-US/Revision_History.html">Revision History</a></li>
</ul>
</li>
</ul>
</div>
<div class="col-xs-12 col-sm-9 col-md-9 main">
<div class="page-header">
<h2>The Python Programming Language</h2>
</div>
<div id="preamble">
<div class="sectionbody">
<div class="paragraph">
<p>Python provides memory safety by default, so low-level security
vulnerabilities are rare and typically needs fixing the Python
interpreter or standard library itself.</p>
</div>
<div class="paragraph">
<p>Other sections with Python-specific advice include:</p>
</div>
<div class="ulist">
<ul>
<li>
<p><a href="#chap-Defensive_Coding-Tasks-Temporary_Files">[chap-Defensive_Coding-Tasks-Temporary_Files]</a></p>
</li>
<li>
<p><a href="#sect-Defensive_Coding-Tasks-Processes-Creation">[sect-Defensive_Coding-Tasks-Processes-Creation]</a></p>
</li>
<li>
<p><a href="#chap-Defensive_Coding-Tasks-Serialization">[chap-Defensive_Coding-Tasks-Serialization]</a>, in
particular <a href="#sect-Defensive_Coding-Tasks-Serialization-Library">[sect-Defensive_Coding-Tasks-Serialization-Library]</a></p>
</li>
<li>
<p><a href="#sect-Defensive_Coding-Tasks-Cryptography-Randomness">[sect-Defensive_Coding-Tasks-Cryptography-Randomness]</a></p>
</li>
</ul>
</div>
</div>
</div>
<div class="sect1">
<h2 id="dangerous-standard-library-features"><a class="anchor" href="#dangerous-standard-library-features"></a>Dangerous Standard Library Features</h2>
<div class="sectionbody">
<div class="paragraph">
<p>Some areas of the standard library, notably the
<code>ctypes</code> module, do not provide memory safety
guarantees comparable to the rest of Python. If such
functionality is used, the advice in <a href="#sect-Defensive_Coding-C-Language">[sect-Defensive_Coding-C-Language]</a> should be followed.</p>
</div>
</div>
</div>
<div class="sect1">
<h2 id="run-time-compilation-and-code-generation"><a class="anchor" href="#run-time-compilation-and-code-generation"></a>Run-time Compilation and Code Generation</h2>
<div class="sectionbody">
<div class="paragraph">
<p>The following Python functions and statements related to code
execution should be avoided:</p>
</div>
<div class="ulist">
<ul>
<li>
<p><code>compile</code></p>
</li>
<li>
<p><code>eval</code></p>
</li>
<li>
<p><code>exec</code></p>
</li>
<li>
<p><code>execfile</code></p>
</li>
</ul>
</div>
<div class="paragraph">
<p>If you need to parse integers or floating point values, use the
<code>int</code> and <code>float</code>
functions instead of <code>eval</code>. Sandboxing
untrusted Python code does not work reliably.</p>
</div>
</div>
</div>
<div class="sect1">
<h2 id="sandboxing"><a class="anchor" href="#sandboxing"></a>Sandboxing</h2>
<div class="sectionbody">
<div class="paragraph">
<p>The <code>rexec</code> Python module cannot safely sandbox
untrusted code and should not be used. The standard CPython
implementation is not suitable for sandboxing.</p>
</div>
</div>
</div>
</div>
</div>
</div>
<div id="bottom" class="text-muted py-3" >
<div class="foot">
<div class="container">
<div class="row footerlinks">
<div class="col-sm-3 col-xs-6 widget">
<h3 class="widget-title">About</h3>
<div class="widget-body">
<dl>
<dd><a href="https://fedoraproject.org/wiki/Overview">About Fedora</a></dd>
<dd><a href="https://getfedora.org/en/sponsors">Sponsors</a></dd>
<dd><a href="https://fedoramagazine.org">Fedora Magazine</a></dd>
<dd><a href="https://fedoraproject.org/wiki/Legal:Main#Legal">Legal</a></dd>
</dl>
<ul class="list-inline">
<li>
<a href="https://www.facebook.com/TheFedoraProject" class="btn-social btn-outline"><i class="fa fa-fw fa-facebook"></i></a>
</li>
<li>
<a href="https://plus.google.com/112917221531140868607" class="btn-social btn-outline"><i class="fa fa-fw fa-google-plus"></i></a>
</li>
<li>
<a href="https://twitter.com/fedora" class="btn-social btn-outline"><i class="fa fa-fw fa-twitter"></i></a>
</li>
</ul>
</div>
</div>
<div class="col-sm-3 col-xs-6 widget">
<h3 class="widget-title uppercase">Download</h3>
<div class="widget-body">
<dl>
<dd><a href="https://getfedora.org/en/workstation/download">Get Fedora Workstation</a></dd>
<dd><a href="https://getfedora.org/en/server/download">Get Fedora Server</a></dd>
<dd><a href="https://getfedora.org/en/atomic/download">Get Fedora Atomic</a></dd>
<dd><a href="https://spins.fedoraproject.org">Fedora Spins</a></dd>
<dd><a href="https://labs.fedoraproject.org">Fedora Labs</a></dd>
<dd><a href="https://arm.fedoraproject.org">Fedora ARM<span class="sup">&reg;</span></a></dd>
<dd><a href="https://alt.fedoraproject.org/">Alternative Downloads</a></dd>
</dl>
</div>
</div>
<div class="col-sm-3 col-xs-6 widget">
<h3 class="widget-title">Support</h3>
<div class="widget-body">
<dl>
<dd><a href="https://fedoraproject.org/wiki/Communicating_and_getting_help">Get Help</a></dd>
<dd><a href="https://ask.fedoraproject.org/">Ask Fedora</a></dd>
<dd><a href="https://fedoraproject.org/wiki/Common_F27_bugs">Common Bugs</a></dd>
<dd><a href="https://developer.fedoraproject.org/">Fedora Developer Portal</a></dd>
<dd><a href="https://docs.fedoraproject.org/f27/install-guide/index.html">Installation Guide</a></dd>
</dl>
</div>
</div>
<div class="col-sm-3 col-xs-6 widget">
<h3 class="widget-title">Join</h3>
<div class="widget-body">
<dl>
<dd><a href="https://fedoraproject.org/wiki/Join">Join Fedora</a></dd>
<dd><a href="http://fedoraplanet.org">Planet Fedora</a></dd>
<dd><a href="https://fedoraproject.org/wiki/SIGs">Fedora SIGs</a></dd>
<dd><a href="https://admin.fedoraproject.org/accounts/">Fedora Account System</a></dd>
<dd><a href="https://fedoracommunity.org/">Fedora Community</a></dd>
</dl>
</div>
</div>
</div> <!-- /row of widgets -->
<div class="row">
<div class="col-md-2">
<div class="widget-body">
<a href="https://www.redhat.com/"><img class="rh-logo" src="../../../master/_images/redhat-logo.png" alt="Red Hat Logo" /></a>
</div>
</div>
<div class="col-md-7">
<div class="widget-body">
<p class="sponsor">Fedora is sponsored by Red Hat.</p>
<p class="sponsor"><a href="https://www.redhat.com/en/technologies/linux-platforms/articles/relationship-between-fedora-and-rhel">Learn more about the relationship between Red Hat and Fedora &raquo;</a></p>
<p class="copy">&copy; 2017 Red Hat, Inc. and others. Please send any comments or corrections to the <a href="https://pagure.io/fedora-docs/docs-fp-o">documentation team</a></p>
</div>
</div>
</div> <!-- /row of widgets -->
</div>
</div>
</div>
<!-- jQuery (necessary for Bootstrap's JavaScript plugins) -->
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>
<!-- Latest compiled and minified JavaScript -->
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/js/bootstrap.min.js"></script>
<script src="../../../master/_javascripts/bootstrap-offcanvas.js" type="text/javascript"></script>
<script type="text/javascript">
/*<![CDATA[*/
$(document).ready(function() {
$("[id^='topicGroup']").on('show.bs.collapse', function (event) {
if (!($(event.target).attr('id').match(/^topicSubGroup/))) {
$(this).parent().find("[id^='tgSpan']").toggleClass("fa-angle-right fa-angle-down");
}
});
$("[id^='topicGroup']").on('hide.bs.collapse', function (event) {
if (!($(event.target).attr('id').match(/^topicSubGroup/))) {
$(this).parent().find("[id^='tgSpan']").toggleClass("fa-angle-right fa-angle-down");
}
});
$("[id^='topicSubGroup']").on('show.bs.collapse', function () {
$(this).parent().find("[id^='sgSpan']").toggleClass("fa-caret-right fa-caret-down");
});
$("[id^='topicSubGroup']").on('hide.bs.collapse', function () {
$(this).parent().find("[id^='sgSpan']").toggleClass("fa-caret-right fa-caret-down");
});
});
/*]]>*/
</script>
</body>
</html>

View file

@ -1,699 +0,0 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta content="IE=edge" http-equiv="X-UA-Compatible">
<meta content="width=device-width, initial-scale=1.0" name="viewport">
<title>Defensive Coding Guide | Defensive Coding Guide | Programming Languages | Shell Programming and bash</title>
<!-- Bootstrap -->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css">
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap-theme.min.css">
<!-- Overpass Font -->
<link rel="stylesheet" href="https://overpass-30e2.kxcdn.com/overpass.css">
<link href="../../../master/_stylesheets/asciibinder.css" rel="stylesheet" />
<!-- HTML5 shim and Respond.js for IE8 support of HTML5 elements and media queries -->
<!-- WARNING: Respond.js doesn't work if you view the page via file:// -->
<!--[if lt IE 9]>
<script src="https://oss.maxcdn.com/html5shiv/3.7.2/html5shiv.min.js"></script>
<script src="https://oss.maxcdn.com/respond/1.4.2/respond.min.js"></script>
<![endif]-->
<link href="../../../master/_images/favicon32x32.png" rel="shortcut icon" type="text/css">
<!--[if IE]><link rel="shortcut icon" href="../../../master/_images/favicon.ico"><![endif]-->
<meta content="AsciiBinder" name="application-name">
</head>
<body>
<div class="navbar navbar-default" role="navigation">
<div class="container-fluid">
<div class="navbar-header">
<a class="navbar-brand" href="https://docs.fedoraproject.org/"><img alt="Fedora Documentation" src="../../../master/_images/fedora.svg"></a>
</div>
</div>
</div>
<div class="container">
<p class="toggle-nav visible-xs pull-left">
<button class="btn btn-default btn-sm" type="button" data-toggle="offcanvas">Toggle nav</button>
</p>
<ol class="breadcrumb">
<li class="sitename">
<a href="../../../index.html">Home</a>
</li>
<li class="hidden-xs active">
<a href="../../en-US/index.html">Defensive Coding Guide </a>
</li>
<li class="hidden-xs active">
<a href="../../en-US/index.html">Defensive Coding Guide</a>
</li>
<li class="hidden-xs active"><a href="../../en-US/programming-languages/C.html">Programming Languages</a></li>
<li class="hidden-xs active">
Shell Programming and bash
</li>
</ol>
<div class="row row-offcanvas row-offcanvas-left">
<div class="col-xs-8 col-sm-3 col-md-3 sidebar sidebar-offcanvas">
<ul class="nav nav-sidebar">
<li class="nav-header">
<a class="" href="#" data-toggle="collapse" data-target="#topicGroup0">
<span id="tgSpan0" class="fa fa-angle-down"></span>Defensive Coding Guide
</a>
<ul id="topicGroup0" class="collapse in list-unstyled">
<li><a class="" href="../../en-US/index.html">Book Information</a></li>
<li class="nav-header">
<a class="" href="#" data-toggle="collapse" data-target="#topicSubGroup-0-1">
<span id="sgSpan-0-1" class="fa fa-caret-down"></span>&nbsp;Programming Languages
</a>
<ul id="topicSubGroup-0-1" class="nav-tertiary list-unstyled collapse in">
<li><a class="" href="../../en-US/programming-languages/C.html">The C Programming Language</a></li>
<li><a class="" href="../../en-US/programming-languages/CXX.html">The C++ Programming&nbsp;Language</a></li>
<li><a class="" href="../../en-US/programming-languages/Java.html">The Java Programming Language</a></li>
<li><a class="" href="../../en-US/programming-languages/Python.html">The Python Programming Language</a></li>
<li><a class=" active" href="../../en-US/programming-languages/Shell.html">Shell Programming and bash</a></li>
<li><a class="" href="../../en-US/programming-languages/Go.html">The Go Programming Language</a></li>
<li><a class="" href="../../en-US/programming-languages/Vala.html">The Vala Programming Language</a></li>
</ul>
</li>
<li class="nav-header">
<a class="" href="#" data-toggle="collapse" data-target="#topicSubGroup-0-2">
<span id="sgSpan-0-2" class="fa fa-caret-right"></span>&nbsp;Specific Programming Tasks
</a>
<ul id="topicSubGroup-0-2" class="nav-tertiary list-unstyled collapse">
<li><a class="" href="../../en-US/tasks/Tasks-Library_Design.html">Library Design</a></li>
<li><a class="" href="../../en-US/tasks/Tasks-Descriptors.html">File Descriptor Management</a></li>
<li><a class="" href="../../en-US/tasks/Tasks-File_System.html">File System Manipulation</a></li>
<li><a class="" href="../../en-US/tasks/Tasks-Temporary_Files.html">Temporary Files</a></li>
<li><a class="" href="../../en-US/tasks/Tasks-Processes.html">Processes</a></li>
<li><a class="" href="../../en-US/tasks/Tasks-Serialization.html">Serialization and Deserialization</a></li>
<li><a class="" href="../../en-US/tasks/Tasks-Cryptography.html">Cryptography</a></li>
<li><a class="" href="../../en-US/tasks/Tasks-Packaging.html">RPM Packaging</a></li>
</ul>
</li>
<li class="nav-header">
<a class="" href="#" data-toggle="collapse" data-target="#topicSubGroup-0-3">
<span id="sgSpan-0-3" class="fa fa-caret-right"></span>&nbsp;Implementing Security Features
</a>
<ul id="topicSubGroup-0-3" class="nav-tertiary list-unstyled collapse">
<li><a class="" href="../../en-US/features/Features-Authentication.html">Authentication and Authorization</a></li>
<li><a class="" href="../../en-US/features/Features-TLS.html">Transport Layer Security (TLS)</a></li>
<li><a class="" href="../../en-US/features/Features-HSM.html">Hardware Security Modules and Smart Cards</a></li>
</ul>
</li>
<li><a class="" href="../../en-US/Revision_History.html">Revision History</a></li>
</ul>
</li>
</ul>
</div>
<div class="col-xs-12 col-sm-9 col-md-9 main">
<div class="page-header">
<h2>Shell Programming and <strong class="application">bash</strong></h2>
</div>
<div id="preamble">
<div class="sectionbody">
<div class="paragraph">
<p>This chapter contains advice about shell programming, specifically
in <strong class="application">bash</strong>. 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.</p>
</div>
</div>
</div>
<div class="sect1">
<h2 id="sect-Defensive_Coding-Shell-Alternatives"><a class="anchor" href="#sect-Defensive_Coding-Shell-Alternatives"></a>Consider Alternatives</h2>
<div class="sectionbody">
<div class="paragraph">
<p>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?</p>
</div>
<div class="paragraph">
<p>For example, Python with its <code>subprocess</code> 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.</p>
</div>
</div>
</div>
<div class="sect1">
<h2 id="sect-Defensive_Coding-Shell-Language"><a class="anchor" href="#sect-Defensive_Coding-Shell-Language"></a>Shell Language Features</h2>
<div class="sectionbody">
<div class="paragraph">
<p>The following sections cover subtleties concerning the shell
programming languages. They have been written with the
<strong class="application">bash</strong> shell in mind, but some of these
features apply to other shells as well.</p>
</div>
<div class="paragraph">
<p>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.</p>
</div>
<div class="sect2">
<h3 id="sect-Defensive_Coding-Shell-Parameter_Expansion"><a class="anchor" href="#sect-Defensive_Coding-Shell-Parameter_Expansion"></a>Parameter Expansion</h3>
<div class="paragraph">
<p>The mechanism by which named shell variables and parameters are
expanded is called <strong>parameter expansion</strong>. The
most basic syntax is
<code>$</code><strong>variable</strong>” or
<code>${</code><strong>variable</strong><code>}</code>”.</p>
</div>
<div class="paragraph">
<p>In almost all cases, a parameter expansion should be enclosed in
double quotation marks <code>&#8220;&#8221;</code>.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code data-lang="bash">external-program &quot;$arg1&quot; &quot;$arg2&quot;</code></pre>
</div>
</div>
<div class="paragraph">
<p>If the double quotation marks are omitted, the value of the
variable will be split according to the current value of the
<code>IFS</code> variable. This may allow the injection of
additional options which are then processed by
<code>external-program</code>.</p>
</div>
<div class="paragraph">
<p>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 <a href="#sect-Defensive_Coding-Shell-Arithmetic">Arithmetic Evaluation</a>.</p>
</div>
</div>
<div class="sect2">
<h3 id="sect-Defensive_Coding-Shell-Double_Expansion"><a class="anchor" href="#sect-Defensive_Coding-Shell-Double_Expansion"></a>Double Expansion</h3>
<div class="paragraph">
<p><strong>Double expansion</strong> occurs when, during the
expansion of a shell variable, not just the variable is expanded,
replacing it by its value, but the <strong>value</strong> 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.</p>
</div>
<div class="paragraph">
<p>The evaluation process is in fact recursive, so a self-referential
expression can cause an out-of-memory condition and a shell crash.</p>
</div>
<div class="paragraph">
<p>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.</p>
</div>
<div class="paragraph">
<p>Double expansion can be requested explicitly with the
<code>eval</code> built-in command, or by invoking a
subshell with “<code>bash -c</code>”. These constructs
should not be used.</p>
</div>
<div class="paragraph">
<p>The following sections give examples of places where implicit
double expansion occurs.</p>
</div>
<div class="sect3">
<h4 id="sect-Defensive_Coding-Shell-Arithmetic"><a class="anchor" href="#sect-Defensive_Coding-Shell-Arithmetic"></a>Arithmetic Evaluation</h4>
<div class="paragraph">
<p><strong>Arithmetic evaluation</strong> 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 <a href="#sect-Defensive_Coding-Shell-Double_Expansion">Double Expansion</a>), 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.</p>
</div>
<div class="paragraph">
<p>Arithmetic evaluation is triggered by the follow constructs:</p>
</div>
<div class="ulist">
<ul>
<li>
<p>The <strong>expression</strong> in
<code>$</code><strong>expression</strong><code></code>
is evaluated. This construct is called <strong>arithmetic
expansion</strong>.</p>
</li>
<li>
<p></p>
<div class="paragraph">
<p><code>$[</code><strong>expression</strong><code>]</code>
is a deprecated syntax with the same effect.</p>
</div>
</li>
<li>
<p>The arguments to the <code>let</code> shell built-in
are evaluated.</p>
</li>
<li>
<p></p>
<div class="paragraph">
<p><code></code><strong>expression</strong><code></code>
is an alternative syntax for “<code>let</code> <strong>expression</strong>”.</p>
</div>
</li>
<li>
<p>Conditional expressions surrounded by
<code>[[</code><code>]]</code>” can trigger
arithmetic evaluation if certain operators such as
<code>-eq</code> are used. (The
<code>test</code> built-in does not perform arithmetic
evaluation, even with integer operators such as
<code>-eq</code>.)</p>
<div class="paragraph">
<p>The conditional expression
<code>[[ $</code><strong>variable</strong> <code>=~</code> <strong>regexp</strong> <code>]]</code>
can be used for input validation, assuming that
<strong>regexp</strong> is a constant regular
expression.
See <a href="#sect-Defensive_Coding-Shell-Input_Validation">Performing Input Validation</a>.</p>
</div>
</li>
<li>
<p>Certain parameter expansions, for example
<code>${</code><strong>variable</strong><code>[</code><strong>expression</strong><code>]}</code>
(array indexing) or
<code>${</code><strong>variable</strong><code>:</code><strong>expression</strong><code>}</code>
(string slicing), trigger arithmetic evaluation of
<strong>expression</strong>.</p>
</li>
<li>
<p>Assignment to array elements using
<strong>array_variable</strong><code>[</code><strong>subscript</strong><code>]=</code><strong>expression</strong>
triggers evaluation of <strong>subscript</strong>, but
not <strong>expression</strong>.</p>
</li>
<li>
<p>The expressions in the arithmetic <code>for</code>
command,
<code>for </code><strong>expression1</strong><code>;</code> <strong>expression2</strong><code>;</code> <strong>expression3</strong><code>; do</code> <strong>commands</strong><code>; done</code>
are evaluated. This does not apply to the regular
for command,
<code>for</code> <strong>variable</strong> <code>in</code> <strong>list</strong><code>; do</code> <strong>commands</strong><code>; done</code>”.</p>
</li>
</ul>
</div>
<div class="admonitionblock important">
<table>
<tr>
<td class="icon">
<i class="fa icon-important" title="Important"></i>
</td>
<td class="content">
<div class="paragraph">
<p>Depending on the <strong class="application">bash</strong> version, the
above list may be incomplete.</p>
</div>
<div class="paragraph">
<p>If faced with a situation where using such shell features
appears necessary, see <a href="#sect-Defensive_Coding-Shell-Alternatives">Consider Alternatives</a>.</p>
</div>
</td>
</tr>
</table>
</div>
<div class="paragraph">
<p>If it is impossible to avoid shell arithmetic on untrusted
inputs, refer to <a href="#sect-Defensive_Coding-Shell-Input_Validation">Performing Input Validation</a>.</p>
</div>
</div>
<div class="sect3">
<h4 id="sect-Defensive_Coding-Shell-Types"><a class="anchor" href="#sect-Defensive_Coding-Shell-Types"></a>Type declarations</h4>
<div class="paragraph">
<p><strong class="application">bash</strong> supports explicit type
declarations for shell variables:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code data-lang="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</code></pre>
</div>
</div>
<div class="paragraph">
<p>Variables can also be declared as arrays by assigning them an
array expression, as in:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code data-lang="bash">array_variable=(1 2 3 4)</code></pre>
</div>
</div>
<div class="paragraph">
<p>Some built-ins (such as <code>mapfile</code>) can
implicitly create array variables.</p>
</div>
<div class="paragraph">
<p>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 <a href="#sect-Defensive_Coding-Shell-Arithmetic">Arithmetic Evaluation</a>.</p>
</div>
<div class="paragraph">
<p>Shell scripts which use integer or array variables should be
rewritten in another, more suitable language. Se <a href="#sect-Defensive_Coding-Shell-Alternatives">Consider Alternatives</a>.</p>
</div>
</div>
</div>
<div class="sect2">
<h3 id="sect-Defensive_Coding-Shell-Obscure"><a class="anchor" href="#sect-Defensive_Coding-Shell-Obscure"></a>Other Obscurities</h3>
<div class="paragraph">
<p>Obscure shell language features should not be used. Examples are:</p>
</div>
<div class="ulist">
<ul>
<li>
<p>Exported functions (<code>export -f</code> or
<code>declare -f</code>).</p>
</li>
<li>
<p>Function names which are not valid variable names, such as
<code>module::function</code>”.</p>
</li>
<li>
<p>The possibility to override built-ins or external commands
with shell functions.</p>
</li>
<li>
<p>Changing the value of the <code>IFS</code> variable to
tokenize strings.</p>
</li>
</ul>
</div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="sect-Defensive_Coding-Shell-Invoke"><a class="anchor" href="#sect-Defensive_Coding-Shell-Invoke"></a>Invoking External Commands</h2>
<div class="sectionbody">
<div class="paragraph">
<p>When passing shell variables as single command line arguments,
they should always be surrounded by double quotes. See
<a href="#sect-Defensive_Coding-Shell-Parameter_Expansion">Parameter Expansion</a>.</p>
</div>
<div class="paragraph">
<p>Care is required when passing untrusted values as positional
parameters to external commands. If the value starts with a hyphen
<code>-</code>”, it may be interpreted by the external
command as an option. Depending on the external program, a
<code>--</code>” 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.)</p>
</div>
<div class="paragraph">
<p>Cleaning the environment before invoking child processes is
difficult to implement in script. <strong class="application">bash</strong>
keeps a hidden list of environment variables which do not correspond
to shell variables, and unsetting them from within a
<strong class="application">bash</strong> script is not possible. To reset
the environment, a script can re-run itself under the “<code>env
-i</code>” 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 “<code>env -i</code>”.</p>
</div>
<div class="admonitionblock important">
<table>
<tr>
<td class="icon">
<i class="fa icon-important" title="Important"></i>
</td>
<td class="content">
<div class="paragraph">
<p>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.</p>
</div>
</td>
</tr>
</table>
</div>
<div class="paragraph">
<p>Checking for failures in executed external commands is recommended.
If no elaborate error recovery is needed, invoking “<code>set
-e</code>” may be sufficient. This causes the script to stop on
the first failed command. However, failures in pipes
(“<code>command1 | command2</code>”) are only detected for the
last command in the pipe, errors in previous commands are ignored.
This can be changed by invoking “<code>set -o pipefail</code>”.
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.</p>
</div>
<div class="paragraph">
<p>See <a href="#sect-Defensive_Coding-Tasks-Processes-Creation">[sect-Defensive_Coding-Tasks-Processes-Creation]</a>
for additional details on creating child processes.</p>
</div>
</div>
</div>
<div class="sect1">
<h2 id="sect-Defensive_Coding-Shell-Temporary_Files"><a class="anchor" href="#sect-Defensive_Coding-Shell-Temporary_Files"></a>Temporary Files</h2>
<div class="sectionbody">
<div class="paragraph">
<p>Temporary files should be created with the
<code>mktemp</code> command, and temporary directories with
<code>mktemp -d</code>”.</p>
</div>
<div class="paragraph">
<p>To clean up temporary files and directories, write a clean-up
shell function and register it as a trap handler, as shown in
<a href="#ex-Defensive_Coding-Tasks-Temporary_Files">Creating and Cleaning up Temporary Files</a>.
Using a separate function avoids issues with proper quoting of
variables.</p>
</div>
<div id="ex-Defensive_Coding-Tasks-Temporary_Files" class="exampleblock">
<div class="title">Example 1. Creating and Cleaning up Temporary Files</div>
<div class="content">
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code data-lang="bash">tmpfile=&quot;$(mktemp)&quot;
cleanup () {
rm -f -- &quot;$tmpfile&quot;
}
trap cleanup 0</code></pre>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="sect-Defensive_Coding-Shell-Input_Validation"><a class="anchor" href="#sect-Defensive_Coding-Shell-Input_Validation"></a>Performing Input Validation</h2>
<div class="sectionbody">
<div class="paragraph">
<p>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 <a href="#sect-Defensive_Coding-Shell-Arithmetic">Arithmetic Evaluation</a>.</p>
</div>
<div class="paragraph">
<p><a href="#ex-Defensive_Coding-Shell-Input_Validation">Input validation in <strong class="application">bash</strong></a>
shows a construct which can be used to check if a string
<code>$value</code>” is an integer. This construct is
specific to <strong class="application">bash</strong> and not portable to
POSIX shells.</p>
</div>
<div id="ex-Defensive_Coding-Shell-Input_Validation" class="exampleblock">
<div class="title">Example 2. Input validation in <strong class="application">bash</strong></div>
<div class="content">
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code data-lang="bash">Unresolved directive in &lt;stdin&gt; - include::../snippets/Shell-Input_Validation.adoc[]</code></pre>
</div>
</div>
</div>
</div>
<div class="paragraph">
<p>Using <code>case</code> 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.</p>
</div>
<div class="paragraph">
<p>The <code>expr</code> external command can give misleading
results (e.g., if the value being checked contains operators
itself) and should not be used.</p>
</div>
</div>
</div>
<div class="sect1">
<h2 id="sect-Defensive_Coding-Shell-Edit_Guard"><a class="anchor" href="#sect-Defensive_Coding-Shell-Edit_Guard"></a>Guarding Shell Scripts Against Changes</h2>
<div class="sectionbody">
<div class="paragraph">
<p><strong class="application">bash</strong> 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.)</p>
</div>
<div class="paragraph">
<p>Therefore, long-running scripts should be guarded against
concurrent modification by putting as much of the program logic
into a <code>main</code> function, and invoking the
<code>main</code> function at the end of the script, using
this syntax:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code data-lang="bash">main &quot;$@&quot; ; exit $?</code></pre>
</div>
</div>
<div class="paragraph">
<p>This construct ensures that <strong class="application">bash</strong> will
stop execution after the <code>main</code> function, instead
of opening the script file and trying to read more commands.</p>
</div>
</div>
</div>
</div>
</div>
</div>
<div id="bottom" class="text-muted py-3" >
<div class="foot">
<div class="container">
<div class="row footerlinks">
<div class="col-sm-3 col-xs-6 widget">
<h3 class="widget-title">About</h3>
<div class="widget-body">
<dl>
<dd><a href="https://fedoraproject.org/wiki/Overview">About Fedora</a></dd>
<dd><a href="https://getfedora.org/en/sponsors">Sponsors</a></dd>
<dd><a href="https://fedoramagazine.org">Fedora Magazine</a></dd>
<dd><a href="https://fedoraproject.org/wiki/Legal:Main#Legal">Legal</a></dd>
</dl>
<ul class="list-inline">
<li>
<a href="https://www.facebook.com/TheFedoraProject" class="btn-social btn-outline"><i class="fa fa-fw fa-facebook"></i></a>
</li>
<li>
<a href="https://plus.google.com/112917221531140868607" class="btn-social btn-outline"><i class="fa fa-fw fa-google-plus"></i></a>
</li>
<li>
<a href="https://twitter.com/fedora" class="btn-social btn-outline"><i class="fa fa-fw fa-twitter"></i></a>
</li>
</ul>
</div>
</div>
<div class="col-sm-3 col-xs-6 widget">
<h3 class="widget-title uppercase">Download</h3>
<div class="widget-body">
<dl>
<dd><a href="https://getfedora.org/en/workstation/download">Get Fedora Workstation</a></dd>
<dd><a href="https://getfedora.org/en/server/download">Get Fedora Server</a></dd>
<dd><a href="https://getfedora.org/en/atomic/download">Get Fedora Atomic</a></dd>
<dd><a href="https://spins.fedoraproject.org">Fedora Spins</a></dd>
<dd><a href="https://labs.fedoraproject.org">Fedora Labs</a></dd>
<dd><a href="https://arm.fedoraproject.org">Fedora ARM<span class="sup">&reg;</span></a></dd>
<dd><a href="https://alt.fedoraproject.org/">Alternative Downloads</a></dd>
</dl>
</div>
</div>
<div class="col-sm-3 col-xs-6 widget">
<h3 class="widget-title">Support</h3>
<div class="widget-body">
<dl>
<dd><a href="https://fedoraproject.org/wiki/Communicating_and_getting_help">Get Help</a></dd>
<dd><a href="https://ask.fedoraproject.org/">Ask Fedora</a></dd>
<dd><a href="https://fedoraproject.org/wiki/Common_F27_bugs">Common Bugs</a></dd>
<dd><a href="https://developer.fedoraproject.org/">Fedora Developer Portal</a></dd>
<dd><a href="https://docs.fedoraproject.org/f27/install-guide/index.html">Installation Guide</a></dd>
</dl>
</div>
</div>
<div class="col-sm-3 col-xs-6 widget">
<h3 class="widget-title">Join</h3>
<div class="widget-body">
<dl>
<dd><a href="https://fedoraproject.org/wiki/Join">Join Fedora</a></dd>
<dd><a href="http://fedoraplanet.org">Planet Fedora</a></dd>
<dd><a href="https://fedoraproject.org/wiki/SIGs">Fedora SIGs</a></dd>
<dd><a href="https://admin.fedoraproject.org/accounts/">Fedora Account System</a></dd>
<dd><a href="https://fedoracommunity.org/">Fedora Community</a></dd>
</dl>
</div>
</div>
</div> <!-- /row of widgets -->
<div class="row">
<div class="col-md-2">
<div class="widget-body">
<a href="https://www.redhat.com/"><img class="rh-logo" src="../../../master/_images/redhat-logo.png" alt="Red Hat Logo" /></a>
</div>
</div>
<div class="col-md-7">
<div class="widget-body">
<p class="sponsor">Fedora is sponsored by Red Hat.</p>
<p class="sponsor"><a href="https://www.redhat.com/en/technologies/linux-platforms/articles/relationship-between-fedora-and-rhel">Learn more about the relationship between Red Hat and Fedora &raquo;</a></p>
<p class="copy">&copy; 2017 Red Hat, Inc. and others. Please send any comments or corrections to the <a href="https://pagure.io/fedora-docs/docs-fp-o">documentation team</a></p>
</div>
</div>
</div> <!-- /row of widgets -->
</div>
</div>
</div>
<!-- jQuery (necessary for Bootstrap's JavaScript plugins) -->
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>
<!-- Latest compiled and minified JavaScript -->
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/js/bootstrap.min.js"></script>
<script src="../../../master/_javascripts/bootstrap-offcanvas.js" type="text/javascript"></script>
<script type="text/javascript">
/*<![CDATA[*/
$(document).ready(function() {
$("[id^='topicGroup']").on('show.bs.collapse', function (event) {
if (!($(event.target).attr('id').match(/^topicSubGroup/))) {
$(this).parent().find("[id^='tgSpan']").toggleClass("fa-angle-right fa-angle-down");
}
});
$("[id^='topicGroup']").on('hide.bs.collapse', function (event) {
if (!($(event.target).attr('id').match(/^topicSubGroup/))) {
$(this).parent().find("[id^='tgSpan']").toggleClass("fa-angle-right fa-angle-down");
}
});
$("[id^='topicSubGroup']").on('show.bs.collapse', function () {
$(this).parent().find("[id^='sgSpan']").toggleClass("fa-caret-right fa-caret-down");
});
$("[id^='topicSubGroup']").on('hide.bs.collapse', function () {
$(this).parent().find("[id^='sgSpan']").toggleClass("fa-caret-right fa-caret-down");
});
});
/*]]>*/
</script>
</body>
</html>

View file

@ -1,273 +0,0 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta content="IE=edge" http-equiv="X-UA-Compatible">
<meta content="width=device-width, initial-scale=1.0" name="viewport">
<title>Defensive Coding Guide | Defensive Coding Guide | Programming Languages | The Vala Programming Language</title>
<!-- Bootstrap -->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css">
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap-theme.min.css">
<!-- Overpass Font -->
<link rel="stylesheet" href="https://overpass-30e2.kxcdn.com/overpass.css">
<link href="../../../master/_stylesheets/asciibinder.css" rel="stylesheet" />
<!-- HTML5 shim and Respond.js for IE8 support of HTML5 elements and media queries -->
<!-- WARNING: Respond.js doesn't work if you view the page via file:// -->
<!--[if lt IE 9]>
<script src="https://oss.maxcdn.com/html5shiv/3.7.2/html5shiv.min.js"></script>
<script src="https://oss.maxcdn.com/respond/1.4.2/respond.min.js"></script>
<![endif]-->
<link href="../../../master/_images/favicon32x32.png" rel="shortcut icon" type="text/css">
<!--[if IE]><link rel="shortcut icon" href="../../../master/_images/favicon.ico"><![endif]-->
<meta content="AsciiBinder" name="application-name">
</head>
<body>
<div class="navbar navbar-default" role="navigation">
<div class="container-fluid">
<div class="navbar-header">
<a class="navbar-brand" href="https://docs.fedoraproject.org/"><img alt="Fedora Documentation" src="../../../master/_images/fedora.svg"></a>
</div>
</div>
</div>
<div class="container">
<p class="toggle-nav visible-xs pull-left">
<button class="btn btn-default btn-sm" type="button" data-toggle="offcanvas">Toggle nav</button>
</p>
<ol class="breadcrumb">
<li class="sitename">
<a href="../../../index.html">Home</a>
</li>
<li class="hidden-xs active">
<a href="../../en-US/index.html">Defensive Coding Guide </a>
</li>
<li class="hidden-xs active">
<a href="../../en-US/index.html">Defensive Coding Guide</a>
</li>
<li class="hidden-xs active"><a href="../../en-US/programming-languages/C.html">Programming Languages</a></li>
<li class="hidden-xs active">
The Vala Programming Language
</li>
</ol>
<div class="row row-offcanvas row-offcanvas-left">
<div class="col-xs-8 col-sm-3 col-md-3 sidebar sidebar-offcanvas">
<ul class="nav nav-sidebar">
<li class="nav-header">
<a class="" href="#" data-toggle="collapse" data-target="#topicGroup0">
<span id="tgSpan0" class="fa fa-angle-down"></span>Defensive Coding Guide
</a>
<ul id="topicGroup0" class="collapse in list-unstyled">
<li><a class="" href="../../en-US/index.html">Book Information</a></li>
<li class="nav-header">
<a class="" href="#" data-toggle="collapse" data-target="#topicSubGroup-0-1">
<span id="sgSpan-0-1" class="fa fa-caret-down"></span>&nbsp;Programming Languages
</a>
<ul id="topicSubGroup-0-1" class="nav-tertiary list-unstyled collapse in">
<li><a class="" href="../../en-US/programming-languages/C.html">The C Programming Language</a></li>
<li><a class="" href="../../en-US/programming-languages/CXX.html">The C++ Programming&nbsp;Language</a></li>
<li><a class="" href="../../en-US/programming-languages/Java.html">The Java Programming Language</a></li>
<li><a class="" href="../../en-US/programming-languages/Python.html">The Python Programming Language</a></li>
<li><a class="" href="../../en-US/programming-languages/Shell.html">Shell Programming and bash</a></li>
<li><a class="" href="../../en-US/programming-languages/Go.html">The Go Programming Language</a></li>
<li><a class=" active" href="../../en-US/programming-languages/Vala.html">The Vala Programming Language</a></li>
</ul>
</li>
<li class="nav-header">
<a class="" href="#" data-toggle="collapse" data-target="#topicSubGroup-0-2">
<span id="sgSpan-0-2" class="fa fa-caret-right"></span>&nbsp;Specific Programming Tasks
</a>
<ul id="topicSubGroup-0-2" class="nav-tertiary list-unstyled collapse">
<li><a class="" href="../../en-US/tasks/Tasks-Library_Design.html">Library Design</a></li>
<li><a class="" href="../../en-US/tasks/Tasks-Descriptors.html">File Descriptor Management</a></li>
<li><a class="" href="../../en-US/tasks/Tasks-File_System.html">File System Manipulation</a></li>
<li><a class="" href="../../en-US/tasks/Tasks-Temporary_Files.html">Temporary Files</a></li>
<li><a class="" href="../../en-US/tasks/Tasks-Processes.html">Processes</a></li>
<li><a class="" href="../../en-US/tasks/Tasks-Serialization.html">Serialization and Deserialization</a></li>
<li><a class="" href="../../en-US/tasks/Tasks-Cryptography.html">Cryptography</a></li>
<li><a class="" href="../../en-US/tasks/Tasks-Packaging.html">RPM Packaging</a></li>
</ul>
</li>
<li class="nav-header">
<a class="" href="#" data-toggle="collapse" data-target="#topicSubGroup-0-3">
<span id="sgSpan-0-3" class="fa fa-caret-right"></span>&nbsp;Implementing Security Features
</a>
<ul id="topicSubGroup-0-3" class="nav-tertiary list-unstyled collapse">
<li><a class="" href="../../en-US/features/Features-Authentication.html">Authentication and Authorization</a></li>
<li><a class="" href="../../en-US/features/Features-TLS.html">Transport Layer Security (TLS)</a></li>
<li><a class="" href="../../en-US/features/Features-HSM.html">Hardware Security Modules and Smart Cards</a></li>
</ul>
</li>
<li><a class="" href="../../en-US/Revision_History.html">Revision History</a></li>
</ul>
</li>
</ul>
</div>
<div class="col-xs-12 col-sm-9 col-md-9 main">
<div class="page-header">
<h2>The Vala Programming Language</h2>
</div>
<div class="paragraph">
<p>Vala is a programming language mainly targeted at GNOME developers.</p>
</div>
<div class="paragraph">
<p>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 <a href="#chap-Defensive_Coding-C">[chap-Defensive_Coding-C]</a> apply.</p>
</div>
<div class="paragraph">
<p>In particular, the following Vala language constructs can result in
undefined behavior at run time:</p>
</div>
<div class="ulist">
<ul>
<li>
<p>Integer arithmetic, as described in <a href="#sect-Defensive_Coding-C-Arithmetic">[sect-Defensive_Coding-C-Arithmetic]</a>.</p>
</li>
<li>
<p>Pointer arithmetic, string subscripting and the
<code>substring</code> method on strings (the
<code>string</code> class in the
<code>glib-2.0</code> 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 <code>substring</code>) where the implementation
would have range information to check the validity of indexes.
See <a href="#sect-Defensive_Coding-C-Pointers">[sect-Defensive_Coding-C-Pointers]</a>.</p>
</li>
<li>
<p>Similarly, Vala only performs garbage collection (through
reference counting) for <code>GObject</code> 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 <a href="#sect-Defensive_Coding-C-Use-After-Free">[sect-Defensive_Coding-C-Use-After-Free]</a>).</p>
</li>
</ul>
</div>
</div>
</div>
</div>
<div id="bottom" class="text-muted py-3" >
<div class="foot">
<div class="container">
<div class="row footerlinks">
<div class="col-sm-3 col-xs-6 widget">
<h3 class="widget-title">About</h3>
<div class="widget-body">
<dl>
<dd><a href="https://fedoraproject.org/wiki/Overview">About Fedora</a></dd>
<dd><a href="https://getfedora.org/en/sponsors">Sponsors</a></dd>
<dd><a href="https://fedoramagazine.org">Fedora Magazine</a></dd>
<dd><a href="https://fedoraproject.org/wiki/Legal:Main#Legal">Legal</a></dd>
</dl>
<ul class="list-inline">
<li>
<a href="https://www.facebook.com/TheFedoraProject" class="btn-social btn-outline"><i class="fa fa-fw fa-facebook"></i></a>
</li>
<li>
<a href="https://plus.google.com/112917221531140868607" class="btn-social btn-outline"><i class="fa fa-fw fa-google-plus"></i></a>
</li>
<li>
<a href="https://twitter.com/fedora" class="btn-social btn-outline"><i class="fa fa-fw fa-twitter"></i></a>
</li>
</ul>
</div>
</div>
<div class="col-sm-3 col-xs-6 widget">
<h3 class="widget-title uppercase">Download</h3>
<div class="widget-body">
<dl>
<dd><a href="https://getfedora.org/en/workstation/download">Get Fedora Workstation</a></dd>
<dd><a href="https://getfedora.org/en/server/download">Get Fedora Server</a></dd>
<dd><a href="https://getfedora.org/en/atomic/download">Get Fedora Atomic</a></dd>
<dd><a href="https://spins.fedoraproject.org">Fedora Spins</a></dd>
<dd><a href="https://labs.fedoraproject.org">Fedora Labs</a></dd>
<dd><a href="https://arm.fedoraproject.org">Fedora ARM<span class="sup">&reg;</span></a></dd>
<dd><a href="https://alt.fedoraproject.org/">Alternative Downloads</a></dd>
</dl>
</div>
</div>
<div class="col-sm-3 col-xs-6 widget">
<h3 class="widget-title">Support</h3>
<div class="widget-body">
<dl>
<dd><a href="https://fedoraproject.org/wiki/Communicating_and_getting_help">Get Help</a></dd>
<dd><a href="https://ask.fedoraproject.org/">Ask Fedora</a></dd>
<dd><a href="https://fedoraproject.org/wiki/Common_F27_bugs">Common Bugs</a></dd>
<dd><a href="https://developer.fedoraproject.org/">Fedora Developer Portal</a></dd>
<dd><a href="https://docs.fedoraproject.org/f27/install-guide/index.html">Installation Guide</a></dd>
</dl>
</div>
</div>
<div class="col-sm-3 col-xs-6 widget">
<h3 class="widget-title">Join</h3>
<div class="widget-body">
<dl>
<dd><a href="https://fedoraproject.org/wiki/Join">Join Fedora</a></dd>
<dd><a href="http://fedoraplanet.org">Planet Fedora</a></dd>
<dd><a href="https://fedoraproject.org/wiki/SIGs">Fedora SIGs</a></dd>
<dd><a href="https://admin.fedoraproject.org/accounts/">Fedora Account System</a></dd>
<dd><a href="https://fedoracommunity.org/">Fedora Community</a></dd>
</dl>
</div>
</div>
</div> <!-- /row of widgets -->
<div class="row">
<div class="col-md-2">
<div class="widget-body">
<a href="https://www.redhat.com/"><img class="rh-logo" src="../../../master/_images/redhat-logo.png" alt="Red Hat Logo" /></a>
</div>
</div>
<div class="col-md-7">
<div class="widget-body">
<p class="sponsor">Fedora is sponsored by Red Hat.</p>
<p class="sponsor"><a href="https://www.redhat.com/en/technologies/linux-platforms/articles/relationship-between-fedora-and-rhel">Learn more about the relationship between Red Hat and Fedora &raquo;</a></p>
<p class="copy">&copy; 2017 Red Hat, Inc. and others. Please send any comments or corrections to the <a href="https://pagure.io/fedora-docs/docs-fp-o">documentation team</a></p>
</div>
</div>
</div> <!-- /row of widgets -->
</div>
</div>
</div>
<!-- jQuery (necessary for Bootstrap's JavaScript plugins) -->
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>
<!-- Latest compiled and minified JavaScript -->
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/js/bootstrap.min.js"></script>
<script src="../../../master/_javascripts/bootstrap-offcanvas.js" type="text/javascript"></script>
<script type="text/javascript">
/*<![CDATA[*/
$(document).ready(function() {
$("[id^='topicGroup']").on('show.bs.collapse', function (event) {
if (!($(event.target).attr('id').match(/^topicSubGroup/))) {
$(this).parent().find("[id^='tgSpan']").toggleClass("fa-angle-right fa-angle-down");
}
});
$("[id^='topicGroup']").on('hide.bs.collapse', function (event) {
if (!($(event.target).attr('id').match(/^topicSubGroup/))) {
$(this).parent().find("[id^='tgSpan']").toggleClass("fa-angle-right fa-angle-down");
}
});
$("[id^='topicSubGroup']").on('show.bs.collapse', function () {
$(this).parent().find("[id^='sgSpan']").toggleClass("fa-caret-right fa-caret-down");
});
$("[id^='topicSubGroup']").on('hide.bs.collapse', function () {
$(this).parent().find("[id^='sgSpan']").toggleClass("fa-caret-right fa-caret-down");
});
});
/*]]>*/
</script>
</body>
</html>

View file

@ -1,428 +0,0 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta content="IE=edge" http-equiv="X-UA-Compatible">
<meta content="width=device-width, initial-scale=1.0" name="viewport">
<title>Defensive Coding Guide | Defensive Coding Guide | Specific Programming Tasks | Cryptography</title>
<!-- Bootstrap -->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css">
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap-theme.min.css">
<!-- Overpass Font -->
<link rel="stylesheet" href="https://overpass-30e2.kxcdn.com/overpass.css">
<link href="../../../master/_stylesheets/asciibinder.css" rel="stylesheet" />
<!-- HTML5 shim and Respond.js for IE8 support of HTML5 elements and media queries -->
<!-- WARNING: Respond.js doesn't work if you view the page via file:// -->
<!--[if lt IE 9]>
<script src="https://oss.maxcdn.com/html5shiv/3.7.2/html5shiv.min.js"></script>
<script src="https://oss.maxcdn.com/respond/1.4.2/respond.min.js"></script>
<![endif]-->
<link href="../../../master/_images/favicon32x32.png" rel="shortcut icon" type="text/css">
<!--[if IE]><link rel="shortcut icon" href="../../../master/_images/favicon.ico"><![endif]-->
<meta content="AsciiBinder" name="application-name">
</head>
<body>
<div class="navbar navbar-default" role="navigation">
<div class="container-fluid">
<div class="navbar-header">
<a class="navbar-brand" href="https://docs.fedoraproject.org/"><img alt="Fedora Documentation" src="../../../master/_images/fedora.svg"></a>
</div>
</div>
</div>
<div class="container">
<p class="toggle-nav visible-xs pull-left">
<button class="btn btn-default btn-sm" type="button" data-toggle="offcanvas">Toggle nav</button>
</p>
<ol class="breadcrumb">
<li class="sitename">
<a href="../../../index.html">Home</a>
</li>
<li class="hidden-xs active">
<a href="../../en-US/index.html">Defensive Coding Guide </a>
</li>
<li class="hidden-xs active">
<a href="../../en-US/index.html">Defensive Coding Guide</a>
</li>
<li class="hidden-xs active"><a href="../../en-US/tasks/Tasks-Library_Design.html">Specific Programming Tasks</a></li>
<li class="hidden-xs active">
Cryptography
</li>
</ol>
<div class="row row-offcanvas row-offcanvas-left">
<div class="col-xs-8 col-sm-3 col-md-3 sidebar sidebar-offcanvas">
<ul class="nav nav-sidebar">
<li class="nav-header">
<a class="" href="#" data-toggle="collapse" data-target="#topicGroup0">
<span id="tgSpan0" class="fa fa-angle-down"></span>Defensive Coding Guide
</a>
<ul id="topicGroup0" class="collapse in list-unstyled">
<li><a class="" href="../../en-US/index.html">Book Information</a></li>
<li class="nav-header">
<a class="" href="#" data-toggle="collapse" data-target="#topicSubGroup-0-1">
<span id="sgSpan-0-1" class="fa fa-caret-right"></span>&nbsp;Programming Languages
</a>
<ul id="topicSubGroup-0-1" class="nav-tertiary list-unstyled collapse">
<li><a class="" href="../../en-US/programming-languages/C.html">The C Programming Language</a></li>
<li><a class="" href="../../en-US/programming-languages/CXX.html">The C++ Programming&nbsp;Language</a></li>
<li><a class="" href="../../en-US/programming-languages/Java.html">The Java Programming Language</a></li>
<li><a class="" href="../../en-US/programming-languages/Python.html">The Python Programming Language</a></li>
<li><a class="" href="../../en-US/programming-languages/Shell.html">Shell Programming and bash</a></li>
<li><a class="" href="../../en-US/programming-languages/Go.html">The Go Programming Language</a></li>
<li><a class="" href="../../en-US/programming-languages/Vala.html">The Vala Programming Language</a></li>
</ul>
</li>
<li class="nav-header">
<a class="" href="#" data-toggle="collapse" data-target="#topicSubGroup-0-2">
<span id="sgSpan-0-2" class="fa fa-caret-down"></span>&nbsp;Specific Programming Tasks
</a>
<ul id="topicSubGroup-0-2" class="nav-tertiary list-unstyled collapse in">
<li><a class="" href="../../en-US/tasks/Tasks-Library_Design.html">Library Design</a></li>
<li><a class="" href="../../en-US/tasks/Tasks-Descriptors.html">File Descriptor Management</a></li>
<li><a class="" href="../../en-US/tasks/Tasks-File_System.html">File System Manipulation</a></li>
<li><a class="" href="../../en-US/tasks/Tasks-Temporary_Files.html">Temporary Files</a></li>
<li><a class="" href="../../en-US/tasks/Tasks-Processes.html">Processes</a></li>
<li><a class="" href="../../en-US/tasks/Tasks-Serialization.html">Serialization and Deserialization</a></li>
<li><a class=" active" href="../../en-US/tasks/Tasks-Cryptography.html">Cryptography</a></li>
<li><a class="" href="../../en-US/tasks/Tasks-Packaging.html">RPM Packaging</a></li>
</ul>
</li>
<li class="nav-header">
<a class="" href="#" data-toggle="collapse" data-target="#topicSubGroup-0-3">
<span id="sgSpan-0-3" class="fa fa-caret-right"></span>&nbsp;Implementing Security Features
</a>
<ul id="topicSubGroup-0-3" class="nav-tertiary list-unstyled collapse">
<li><a class="" href="../../en-US/features/Features-Authentication.html">Authentication and Authorization</a></li>
<li><a class="" href="../../en-US/features/Features-TLS.html">Transport Layer Security (TLS)</a></li>
<li><a class="" href="../../en-US/features/Features-HSM.html">Hardware Security Modules and Smart Cards</a></li>
</ul>
</li>
<li><a class="" href="../../en-US/Revision_History.html">Revision History</a></li>
</ul>
</li>
</ul>
</div>
<div class="col-xs-12 col-sm-9 col-md-9 main">
<div class="page-header">
<h2>Cryptography</h2>
</div>
<div class="sect1">
<h2 id="primitives"><a class="anchor" href="#primitives"></a>Primitives</h2>
<div class="sectionbody">
<div class="paragraph">
<p>Choosing from the following cryptographic primitives is
recommended:</p>
</div>
<div class="ulist">
<ul>
<li>
<p>RSA with 2048-bit keys and OAEP or PSS
padding</p>
</li>
<li>
<p>AES-128 in CBC mode</p>
</li>
<li>
<p>AES-128 in GCM mode</p>
</li>
<li>
<p>AES-256 in CBC mode</p>
</li>
<li>
<p>AES-256 in GCM mode</p>
</li>
<li>
<p>SHA-256</p>
</li>
<li>
<p>HMAC-SHA-256</p>
</li>
<li>
<p>HMAC-SHA-1</p>
</li>
</ul>
</div>
<div class="paragraph">
<p>Other cryptographic algorithms can be used if they are required
for interoperability with existing software:</p>
</div>
<div class="ulist">
<ul>
<li>
<p>RSA with key sizes larger than 1024
and legacy padding</p>
</li>
<li>
<p>AES-192</p>
</li>
<li>
<p>3DES (triple DES, with two or three 56-bit keys),
but strongly discouraged</p>
</li>
<li>
<p>RC4 (but very, very strongly discouraged)</p>
</li>
<li>
<p>SHA-1</p>
</li>
<li>
<p>HMAC-MD5</p>
</li>
</ul>
</div>
<div class="admonitionblock important">
<table>
<tr>
<td class="icon">
<i class="fa icon-important" title="Important"></i>
</td>
<td class="content">
<div class="title">Important</div>
<div class="paragraph">
<p>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 (<a href="#chap-Defensive_Coding-TLS">[chap-Defensive_Coding-TLS]</a>).</p>
</div>
<div class="paragraph">
<p>In particular, when using AES in CBC mode, it is necessary to
add integrity checking by other means, preferably using
HMAC-SHA-256 and <strong>after</strong> encryption (that
is, on the encrypted cipher text). For AES in GCM mode,
correct construction of nonces is absolutely essential.</p>
</div>
</td>
</tr>
</table>
</div>
</div>
</div>
<div class="sect1">
<h2 id="randomness"><a class="anchor" href="#randomness"></a>Randomness</h2>
<div class="sectionbody">
<div class="paragraph">
<p>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.</p>
</div>
<div class="ulist">
<ul>
<li>
<p><code>PK11_GenerateRandom</code> in the NSS library
(usable for high data rates)</p>
</li>
<li>
<p><code>RAND_bytes</code> in the OpenSSL library
(usable for high data rates)</p>
</li>
<li>
<p><code>gnutls_rnd</code> in GNUTLS, with
<code>GNUTLS_RND_RANDOM</code> as the first argument
(usable for high data rates)</p>
</li>
<li>
<p><code>java.security.SecureRandom</code> in Java
(usable for high data rates)</p>
</li>
<li>
<p><code>os.urandom</code> in Python</p>
</li>
<li>
<p>The <code>getrandom</code> system call since glibc 2.25</p>
</li>
<li>
<p>The <code>getentropy</code> call since glibc 2.25</p>
</li>
<li>
<p>Reading from the <code>/dev/urandom</code>
character device</p>
</li>
</ul>
</div>
<div class="paragraph">
<p>All these functions should be non-blocking, and they should not
wait until physical randomness becomes available. (Some
cryptography providers for Java can cause
<code>java.security.SecureRandom</code> to block, however.)
Those functions which do not obtain all bits directly from
<code>/dev/urandom</code> are suitable for high data
rates because they do not deplete the system-wide entropy pool.</p>
</div>
<div class="admonitionblock important">
<table>
<tr>
<td class="icon">
<i class="fa icon-important" title="Important"></i>
</td>
<td class="content">
<div class="title">Difficult to use API</div>
<div class="paragraph">
<p>Both <code>RAND_bytes</code> and
<code>PK11_GenerateRandom</code> have three-state
return values (with conflicting meanings). Careful error
checking is required. Please review the documentation when
using these functions.</p>
</div>
</td>
</tr>
</table>
</div>
<div class="admonitionblock important">
<table>
<tr>
<td class="icon">
<i class="fa icon-important" title="Important"></i>
</td>
<td class="content">
<div class="title">Difficult to use API</div>
<div class="paragraph">
<p>The <code>getrandom</code> system call has three-state
return values, hence requires careful error checking.</p>
</div>
<div class="paragraph">
<p>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 <code>syscall(SYS_getrandom, (void*)dest, (size_t)size, (unsigned int)0)</code>.
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.</p>
</div>
</td>
</tr>
</table>
</div>
<div class="paragraph">
<p>Other sources of randomness should be considered predictable.</p>
</div>
<div class="paragraph">
<p>Generating randomness for cryptographic keys in long-term use
may need different steps and is best left to cryptographic
libraries.</p>
</div>
</div>
</div>
</div>
</div>
</div>
<div id="bottom" class="text-muted py-3" >
<div class="foot">
<div class="container">
<div class="row footerlinks">
<div class="col-sm-3 col-xs-6 widget">
<h3 class="widget-title">About</h3>
<div class="widget-body">
<dl>
<dd><a href="https://fedoraproject.org/wiki/Overview">About Fedora</a></dd>
<dd><a href="https://getfedora.org/en/sponsors">Sponsors</a></dd>
<dd><a href="https://fedoramagazine.org">Fedora Magazine</a></dd>
<dd><a href="https://fedoraproject.org/wiki/Legal:Main#Legal">Legal</a></dd>
</dl>
<ul class="list-inline">
<li>
<a href="https://www.facebook.com/TheFedoraProject" class="btn-social btn-outline"><i class="fa fa-fw fa-facebook"></i></a>
</li>
<li>
<a href="https://plus.google.com/112917221531140868607" class="btn-social btn-outline"><i class="fa fa-fw fa-google-plus"></i></a>
</li>
<li>
<a href="https://twitter.com/fedora" class="btn-social btn-outline"><i class="fa fa-fw fa-twitter"></i></a>
</li>
</ul>
</div>
</div>
<div class="col-sm-3 col-xs-6 widget">
<h3 class="widget-title uppercase">Download</h3>
<div class="widget-body">
<dl>
<dd><a href="https://getfedora.org/en/workstation/download">Get Fedora Workstation</a></dd>
<dd><a href="https://getfedora.org/en/server/download">Get Fedora Server</a></dd>
<dd><a href="https://getfedora.org/en/atomic/download">Get Fedora Atomic</a></dd>
<dd><a href="https://spins.fedoraproject.org">Fedora Spins</a></dd>
<dd><a href="https://labs.fedoraproject.org">Fedora Labs</a></dd>
<dd><a href="https://arm.fedoraproject.org">Fedora ARM<span class="sup">&reg;</span></a></dd>
<dd><a href="https://alt.fedoraproject.org/">Alternative Downloads</a></dd>
</dl>
</div>
</div>
<div class="col-sm-3 col-xs-6 widget">
<h3 class="widget-title">Support</h3>
<div class="widget-body">
<dl>
<dd><a href="https://fedoraproject.org/wiki/Communicating_and_getting_help">Get Help</a></dd>
<dd><a href="https://ask.fedoraproject.org/">Ask Fedora</a></dd>
<dd><a href="https://fedoraproject.org/wiki/Common_F27_bugs">Common Bugs</a></dd>
<dd><a href="https://developer.fedoraproject.org/">Fedora Developer Portal</a></dd>
<dd><a href="https://docs.fedoraproject.org/f27/install-guide/index.html">Installation Guide</a></dd>
</dl>
</div>
</div>
<div class="col-sm-3 col-xs-6 widget">
<h3 class="widget-title">Join</h3>
<div class="widget-body">
<dl>
<dd><a href="https://fedoraproject.org/wiki/Join">Join Fedora</a></dd>
<dd><a href="http://fedoraplanet.org">Planet Fedora</a></dd>
<dd><a href="https://fedoraproject.org/wiki/SIGs">Fedora SIGs</a></dd>
<dd><a href="https://admin.fedoraproject.org/accounts/">Fedora Account System</a></dd>
<dd><a href="https://fedoracommunity.org/">Fedora Community</a></dd>
</dl>
</div>
</div>
</div> <!-- /row of widgets -->
<div class="row">
<div class="col-md-2">
<div class="widget-body">
<a href="https://www.redhat.com/"><img class="rh-logo" src="../../../master/_images/redhat-logo.png" alt="Red Hat Logo" /></a>
</div>
</div>
<div class="col-md-7">
<div class="widget-body">
<p class="sponsor">Fedora is sponsored by Red Hat.</p>
<p class="sponsor"><a href="https://www.redhat.com/en/technologies/linux-platforms/articles/relationship-between-fedora-and-rhel">Learn more about the relationship between Red Hat and Fedora &raquo;</a></p>
<p class="copy">&copy; 2017 Red Hat, Inc. and others. Please send any comments or corrections to the <a href="https://pagure.io/fedora-docs/docs-fp-o">documentation team</a></p>
</div>
</div>
</div> <!-- /row of widgets -->
</div>
</div>
</div>
<!-- jQuery (necessary for Bootstrap's JavaScript plugins) -->
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>
<!-- Latest compiled and minified JavaScript -->
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/js/bootstrap.min.js"></script>
<script src="../../../master/_javascripts/bootstrap-offcanvas.js" type="text/javascript"></script>
<script type="text/javascript">
/*<![CDATA[*/
$(document).ready(function() {
$("[id^='topicGroup']").on('show.bs.collapse', function (event) {
if (!($(event.target).attr('id').match(/^topicSubGroup/))) {
$(this).parent().find("[id^='tgSpan']").toggleClass("fa-angle-right fa-angle-down");
}
});
$("[id^='topicGroup']").on('hide.bs.collapse', function (event) {
if (!($(event.target).attr('id').match(/^topicSubGroup/))) {
$(this).parent().find("[id^='tgSpan']").toggleClass("fa-angle-right fa-angle-down");
}
});
$("[id^='topicSubGroup']").on('show.bs.collapse', function () {
$(this).parent().find("[id^='sgSpan']").toggleClass("fa-caret-right fa-caret-down");
});
$("[id^='topicSubGroup']").on('hide.bs.collapse', function () {
$(this).parent().find("[id^='sgSpan']").toggleClass("fa-caret-right fa-caret-down");
});
});
/*]]>*/
</script>
</body>
</html>

View file

@ -1,497 +0,0 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta content="IE=edge" http-equiv="X-UA-Compatible">
<meta content="width=device-width, initial-scale=1.0" name="viewport">
<title>Defensive Coding Guide | Defensive Coding Guide | Specific Programming Tasks | File Descriptor Management</title>
<!-- Bootstrap -->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css">
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap-theme.min.css">
<!-- Overpass Font -->
<link rel="stylesheet" href="https://overpass-30e2.kxcdn.com/overpass.css">
<link href="../../../master/_stylesheets/asciibinder.css" rel="stylesheet" />
<!-- HTML5 shim and Respond.js for IE8 support of HTML5 elements and media queries -->
<!-- WARNING: Respond.js doesn't work if you view the page via file:// -->
<!--[if lt IE 9]>
<script src="https://oss.maxcdn.com/html5shiv/3.7.2/html5shiv.min.js"></script>
<script src="https://oss.maxcdn.com/respond/1.4.2/respond.min.js"></script>
<![endif]-->
<link href="../../../master/_images/favicon32x32.png" rel="shortcut icon" type="text/css">
<!--[if IE]><link rel="shortcut icon" href="../../../master/_images/favicon.ico"><![endif]-->
<meta content="AsciiBinder" name="application-name">
</head>
<body>
<div class="navbar navbar-default" role="navigation">
<div class="container-fluid">
<div class="navbar-header">
<a class="navbar-brand" href="https://docs.fedoraproject.org/"><img alt="Fedora Documentation" src="../../../master/_images/fedora.svg"></a>
</div>
</div>
</div>
<div class="container">
<p class="toggle-nav visible-xs pull-left">
<button class="btn btn-default btn-sm" type="button" data-toggle="offcanvas">Toggle nav</button>
</p>
<ol class="breadcrumb">
<li class="sitename">
<a href="../../../index.html">Home</a>
</li>
<li class="hidden-xs active">
<a href="../../en-US/index.html">Defensive Coding Guide </a>
</li>
<li class="hidden-xs active">
<a href="../../en-US/index.html">Defensive Coding Guide</a>
</li>
<li class="hidden-xs active"><a href="../../en-US/tasks/Tasks-Library_Design.html">Specific Programming Tasks</a></li>
<li class="hidden-xs active">
File Descriptor Management
</li>
</ol>
<div class="row row-offcanvas row-offcanvas-left">
<div class="col-xs-8 col-sm-3 col-md-3 sidebar sidebar-offcanvas">
<ul class="nav nav-sidebar">
<li class="nav-header">
<a class="" href="#" data-toggle="collapse" data-target="#topicGroup0">
<span id="tgSpan0" class="fa fa-angle-down"></span>Defensive Coding Guide
</a>
<ul id="topicGroup0" class="collapse in list-unstyled">
<li><a class="" href="../../en-US/index.html">Book Information</a></li>
<li class="nav-header">
<a class="" href="#" data-toggle="collapse" data-target="#topicSubGroup-0-1">
<span id="sgSpan-0-1" class="fa fa-caret-right"></span>&nbsp;Programming Languages
</a>
<ul id="topicSubGroup-0-1" class="nav-tertiary list-unstyled collapse">
<li><a class="" href="../../en-US/programming-languages/C.html">The C Programming Language</a></li>
<li><a class="" href="../../en-US/programming-languages/CXX.html">The C++ Programming&nbsp;Language</a></li>
<li><a class="" href="../../en-US/programming-languages/Java.html">The Java Programming Language</a></li>
<li><a class="" href="../../en-US/programming-languages/Python.html">The Python Programming Language</a></li>
<li><a class="" href="../../en-US/programming-languages/Shell.html">Shell Programming and bash</a></li>
<li><a class="" href="../../en-US/programming-languages/Go.html">The Go Programming Language</a></li>
<li><a class="" href="../../en-US/programming-languages/Vala.html">The Vala Programming Language</a></li>
</ul>
</li>
<li class="nav-header">
<a class="" href="#" data-toggle="collapse" data-target="#topicSubGroup-0-2">
<span id="sgSpan-0-2" class="fa fa-caret-down"></span>&nbsp;Specific Programming Tasks
</a>
<ul id="topicSubGroup-0-2" class="nav-tertiary list-unstyled collapse in">
<li><a class="" href="../../en-US/tasks/Tasks-Library_Design.html">Library Design</a></li>
<li><a class=" active" href="../../en-US/tasks/Tasks-Descriptors.html">File Descriptor Management</a></li>
<li><a class="" href="../../en-US/tasks/Tasks-File_System.html">File System Manipulation</a></li>
<li><a class="" href="../../en-US/tasks/Tasks-Temporary_Files.html">Temporary Files</a></li>
<li><a class="" href="../../en-US/tasks/Tasks-Processes.html">Processes</a></li>
<li><a class="" href="../../en-US/tasks/Tasks-Serialization.html">Serialization and Deserialization</a></li>
<li><a class="" href="../../en-US/tasks/Tasks-Cryptography.html">Cryptography</a></li>
<li><a class="" href="../../en-US/tasks/Tasks-Packaging.html">RPM Packaging</a></li>
</ul>
</li>
<li class="nav-header">
<a class="" href="#" data-toggle="collapse" data-target="#topicSubGroup-0-3">
<span id="sgSpan-0-3" class="fa fa-caret-right"></span>&nbsp;Implementing Security Features
</a>
<ul id="topicSubGroup-0-3" class="nav-tertiary list-unstyled collapse">
<li><a class="" href="../../en-US/features/Features-Authentication.html">Authentication and Authorization</a></li>
<li><a class="" href="../../en-US/features/Features-TLS.html">Transport Layer Security (TLS)</a></li>
<li><a class="" href="../../en-US/features/Features-HSM.html">Hardware Security Modules and Smart Cards</a></li>
</ul>
</li>
<li><a class="" href="../../en-US/Revision_History.html">Revision History</a></li>
</ul>
</li>
</ul>
</div>
<div class="col-xs-12 col-sm-9 col-md-9 main">
<div class="page-header">
<h2>File Descriptor Management</h2>
</div>
<div id="preamble">
<div class="sectionbody">
<div class="paragraph">
<p>File descriptors underlie all input/output mechanisms offered by
the system. They are used to implementation the <code>FILE
*</code>-based functions found in
<code>&lt;stdio.h&gt;</code>, and all the file and network
communication facilities provided by the Python and Java
environments are eventually implemented in them.</p>
</div>
<div class="paragraph">
<p>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.</p>
</div>
</div>
</div>
<div class="sect1">
<h2 id="closing-descriptors"><a class="anchor" href="#closing-descriptors"></a>Closing Descriptors</h2>
<div class="sectionbody">
<div class="paragraph">
<p>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 <a href="#sect-Defensive_Coding-Tasks-Descriptors-Limit">Dealing with the <code>select</code> Limit</a>), 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.</p>
</div>
<div class="sect2">
<h3 id="error-handling-during-descriptor-close"><a class="anchor" href="#error-handling-during-descriptor-close"></a>Error Handling during Descriptor Close</h3>
<div class="paragraph">
<p>The <code>close</code> system call is always
successful in the sense that the passed file descriptor is
never valid after the function has been called. However,
<code>close</code> 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 <code>O_SYNC</code> or use
<code>fsync</code> or <code>fdatasync</code>, and
may also have to <code>fsync</code> the directory
containing the file.</p>
</div>
</div>
<div class="sect2">
<h3 id="closing-descriptors-and-race-conditions"><a class="anchor" href="#closing-descriptors-and-race-conditions"></a>Closing Descriptors and Race Conditions</h3>
<div class="paragraph">
<p>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.</p>
</div>
<div class="paragraph">
<p>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
<code>socketpair</code>, close one of the descriptors,
and call <code>shutdown(fd, SHUTRDWR)</code> on the
other.</p>
</div>
<div class="paragraph">
<p>When a descriptor is closed concurrently, the program does not
call <code>close</code> on the descriptor. Instead it
program uses <code>dup2</code> 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).</p>
</div>
<div class="paragraph">
<p>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.</p>
</div>
</div>
<div class="sect2">
<h3 id="lingering-state-after-close"><a class="anchor" href="#lingering-state-after-close"></a>Lingering State after Close</h3>
<div class="paragraph">
<p>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.</p>
</div>
<div class="paragraph">
<p>The <code>SO_LINGER</code> socket option alters the
behavior of <code>close</code>, 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 <code>close</code>
call, causing scalability issues.</p>
</div>
<div class="paragraph">
<p>Currently, there is no application-level countermeasure which
applies universally. Mitigation is possible with
<strong class="application">iptables</strong> (the
<code>connlimit</code> match type in particular) and
specialized filtering devices for denial-of-service network
traffic.</p>
</div>
<div class="paragraph">
<p>These problems are not related to the
<code>TIME_WAIT</code> state commonly seen in
<strong class="application">netstat</strong> output. The kernel
automatically expires such sockets if necessary.</p>
</div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="sect-Defensive_Coding-Tasks-Descriptors-Child_Processes"><a class="anchor" href="#sect-Defensive_Coding-Tasks-Descriptors-Child_Processes"></a>Preventing File Descriptor Leaks to Child Processes</h2>
<div class="sectionbody">
<div class="paragraph">
<p>Child processes created with <code>fork</code> 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 <code>execve</code>
(or any of the other functions such as <code>system</code>
or <code>posix_spawn</code>).</p>
</div>
<div class="paragraph">
<p>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:</p>
</div>
<div class="ulist">
<ul>
<li>
<p>Set the close-on-exec flag on all newly created file
descriptors. Traditionally, this flag is controlled by the
<code>FD_CLOEXEC</code> flag, using
<code>F_GETFD</code> and <code>F_SETFD</code>
operations of the <code>fcntl</code> function.</p>
<div class="paragraph">
<p>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
<code>FD_CLOEXEC</code> was set. Therefore, many system
calls which create descriptors (such as
<code>open</code> and <code>openat</code>)
now accept the <code>O_CLOEXEC</code> flag
(<code>SOCK_CLOEXEC</code> for
<code>socket</code> and
<code>socketpair</code>), which cause the
<code>FD_CLOEXEC</code> flag to be set for the file
descriptor in an atomic fashion. In addition, a few new
systems calls were introduced, such as
<code>pipe2</code> and <code>dup3</code>.</p>
</div>
<div class="paragraph">
<p>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.</p>
</div>
</li>
<li>
<p>After calling <code>fork</code>, but before creating
a new process image with <code>execve</code>, all
file descriptors which the child process will not need are
closed.</p>
<div class="paragraph">
<p>Traditionally, this was implemented as a loop over file
descriptors ranging from <code>3</code> to
<code>255</code> and later <code>1023</code>.
But this is only an approximation because it is possible to
create file descriptors outside this range easily (see <a href="#sect-Defensive_Coding-Tasks-Descriptors-Limit">Dealing with the <code>select</code> Limit</a>).
Another approach reads <code>/proc/self/fd</code>
and closes the unexpected descriptors listed there, but this
approach is much slower.</p>
</div>
</li>
</ul>
</div>
<div class="paragraph">
<p>At present, environments which care about file descriptor
leakage implement the second approach. OpenJDK 6 and 7
are among them.</p>
</div>
</div>
</div>
<div class="sect1">
<h2 id="sect-Defensive_Coding-Tasks-Descriptors-Limit"><a class="anchor" href="#sect-Defensive_Coding-Tasks-Descriptors-Limit"></a>Dealing with the <code>select</code> Limit</h2>
<div class="sectionbody">
<div class="paragraph">
<p>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.</p>
</div>
<div class="paragraph">
<p>The <code>select</code> function only supports a
maximum of <code>FD_SETSIZE</code> file descriptors
(that is, the maximum permitted value for a file descriptor
is <code>FD_SETSIZE - 1</code>, usually 1023.) If a
process opens many files, descriptors may exceed such
limits. It is impossible to query such descriptors using
<code>select</code>.</p>
</div>
<div class="paragraph">
<p>If a library which creates many file descriptors is used in
the same process as a library which uses
<code>select</code>, at least one of them needs to
be changed.
Calls to <code>select</code> can be replaced with
calls to <code>poll</code> or another event handling
mechanism. Replacing the <code>select</code> function
is the recommended approach.</p>
</div>
<div class="paragraph">
<p>Alternatively, the library with high descriptor usage can
relocate descriptors above the <code>FD_SETSIZE</code>
limit using the following procedure.</p>
</div>
<div class="ulist">
<ul>
<li>
<p>Create the file descriptor <code>fd</code> as
usual, preferably with the <code>O_CLOEXEC</code>
flag.</p>
</li>
<li>
<p>Before doing anything else with the descriptor
<code>fd</code>, invoke:</p>
</li>
</ul>
</div>
<div class="listingblock">
<div class="content">
<pre> int newfd = fcntl(fd, F_DUPFD_CLOEXEC, (long)FD_SETSIZE);</pre>
</div>
</div>
<div class="ulist">
<ul>
<li>
<p>Check that <code>newfd</code> result is
non-negative, otherwise close <code>fd</code> and
report an error, and return.</p>
</li>
<li>
<p>Close <code>fd</code> and continue to use
<code>newfd</code>.</p>
</li>
</ul>
</div>
<div class="paragraph">
<p>The new descriptor has been allocated above the
<code>FD_SETSIZE</code>. Even though this algorithm
is racy in the sense that the <code>FD_SETSIZE</code>
first descriptors could fill up, a very high degree of
physical parallelism is required before this becomes a problem.</p>
</div>
</div>
</div>
</div>
</div>
</div>
<div id="bottom" class="text-muted py-3" >
<div class="foot">
<div class="container">
<div class="row footerlinks">
<div class="col-sm-3 col-xs-6 widget">
<h3 class="widget-title">About</h3>
<div class="widget-body">
<dl>
<dd><a href="https://fedoraproject.org/wiki/Overview">About Fedora</a></dd>
<dd><a href="https://getfedora.org/en/sponsors">Sponsors</a></dd>
<dd><a href="https://fedoramagazine.org">Fedora Magazine</a></dd>
<dd><a href="https://fedoraproject.org/wiki/Legal:Main#Legal">Legal</a></dd>
</dl>
<ul class="list-inline">
<li>
<a href="https://www.facebook.com/TheFedoraProject" class="btn-social btn-outline"><i class="fa fa-fw fa-facebook"></i></a>
</li>
<li>
<a href="https://plus.google.com/112917221531140868607" class="btn-social btn-outline"><i class="fa fa-fw fa-google-plus"></i></a>
</li>
<li>
<a href="https://twitter.com/fedora" class="btn-social btn-outline"><i class="fa fa-fw fa-twitter"></i></a>
</li>
</ul>
</div>
</div>
<div class="col-sm-3 col-xs-6 widget">
<h3 class="widget-title uppercase">Download</h3>
<div class="widget-body">
<dl>
<dd><a href="https://getfedora.org/en/workstation/download">Get Fedora Workstation</a></dd>
<dd><a href="https://getfedora.org/en/server/download">Get Fedora Server</a></dd>
<dd><a href="https://getfedora.org/en/atomic/download">Get Fedora Atomic</a></dd>
<dd><a href="https://spins.fedoraproject.org">Fedora Spins</a></dd>
<dd><a href="https://labs.fedoraproject.org">Fedora Labs</a></dd>
<dd><a href="https://arm.fedoraproject.org">Fedora ARM<span class="sup">&reg;</span></a></dd>
<dd><a href="https://alt.fedoraproject.org/">Alternative Downloads</a></dd>
</dl>
</div>
</div>
<div class="col-sm-3 col-xs-6 widget">
<h3 class="widget-title">Support</h3>
<div class="widget-body">
<dl>
<dd><a href="https://fedoraproject.org/wiki/Communicating_and_getting_help">Get Help</a></dd>
<dd><a href="https://ask.fedoraproject.org/">Ask Fedora</a></dd>
<dd><a href="https://fedoraproject.org/wiki/Common_F27_bugs">Common Bugs</a></dd>
<dd><a href="https://developer.fedoraproject.org/">Fedora Developer Portal</a></dd>
<dd><a href="https://docs.fedoraproject.org/f27/install-guide/index.html">Installation Guide</a></dd>
</dl>
</div>
</div>
<div class="col-sm-3 col-xs-6 widget">
<h3 class="widget-title">Join</h3>
<div class="widget-body">
<dl>
<dd><a href="https://fedoraproject.org/wiki/Join">Join Fedora</a></dd>
<dd><a href="http://fedoraplanet.org">Planet Fedora</a></dd>
<dd><a href="https://fedoraproject.org/wiki/SIGs">Fedora SIGs</a></dd>
<dd><a href="https://admin.fedoraproject.org/accounts/">Fedora Account System</a></dd>
<dd><a href="https://fedoracommunity.org/">Fedora Community</a></dd>
</dl>
</div>
</div>
</div> <!-- /row of widgets -->
<div class="row">
<div class="col-md-2">
<div class="widget-body">
<a href="https://www.redhat.com/"><img class="rh-logo" src="../../../master/_images/redhat-logo.png" alt="Red Hat Logo" /></a>
</div>
</div>
<div class="col-md-7">
<div class="widget-body">
<p class="sponsor">Fedora is sponsored by Red Hat.</p>
<p class="sponsor"><a href="https://www.redhat.com/en/technologies/linux-platforms/articles/relationship-between-fedora-and-rhel">Learn more about the relationship between Red Hat and Fedora &raquo;</a></p>
<p class="copy">&copy; 2017 Red Hat, Inc. and others. Please send any comments or corrections to the <a href="https://pagure.io/fedora-docs/docs-fp-o">documentation team</a></p>
</div>
</div>
</div> <!-- /row of widgets -->
</div>
</div>
</div>
<!-- jQuery (necessary for Bootstrap's JavaScript plugins) -->
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>
<!-- Latest compiled and minified JavaScript -->
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/js/bootstrap.min.js"></script>
<script src="../../../master/_javascripts/bootstrap-offcanvas.js" type="text/javascript"></script>
<script type="text/javascript">
/*<![CDATA[*/
$(document).ready(function() {
$("[id^='topicGroup']").on('show.bs.collapse', function (event) {
if (!($(event.target).attr('id').match(/^topicSubGroup/))) {
$(this).parent().find("[id^='tgSpan']").toggleClass("fa-angle-right fa-angle-down");
}
});
$("[id^='topicGroup']").on('hide.bs.collapse', function (event) {
if (!($(event.target).attr('id').match(/^topicSubGroup/))) {
$(this).parent().find("[id^='tgSpan']").toggleClass("fa-angle-right fa-angle-down");
}
});
$("[id^='topicSubGroup']").on('show.bs.collapse', function () {
$(this).parent().find("[id^='sgSpan']").toggleClass("fa-caret-right fa-caret-down");
});
$("[id^='topicSubGroup']").on('hide.bs.collapse', function () {
$(this).parent().find("[id^='sgSpan']").toggleClass("fa-caret-right fa-caret-down");
});
});
/*]]>*/
</script>
</body>
</html>

View file

@ -1,548 +0,0 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta content="IE=edge" http-equiv="X-UA-Compatible">
<meta content="width=device-width, initial-scale=1.0" name="viewport">
<title>Defensive Coding Guide | Defensive Coding Guide | Specific Programming Tasks | File System Manipulation</title>
<!-- Bootstrap -->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css">
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap-theme.min.css">
<!-- Overpass Font -->
<link rel="stylesheet" href="https://overpass-30e2.kxcdn.com/overpass.css">
<link href="../../../master/_stylesheets/asciibinder.css" rel="stylesheet" />
<!-- HTML5 shim and Respond.js for IE8 support of HTML5 elements and media queries -->
<!-- WARNING: Respond.js doesn't work if you view the page via file:// -->
<!--[if lt IE 9]>
<script src="https://oss.maxcdn.com/html5shiv/3.7.2/html5shiv.min.js"></script>
<script src="https://oss.maxcdn.com/respond/1.4.2/respond.min.js"></script>
<![endif]-->
<link href="../../../master/_images/favicon32x32.png" rel="shortcut icon" type="text/css">
<!--[if IE]><link rel="shortcut icon" href="../../../master/_images/favicon.ico"><![endif]-->
<meta content="AsciiBinder" name="application-name">
</head>
<body>
<div class="navbar navbar-default" role="navigation">
<div class="container-fluid">
<div class="navbar-header">
<a class="navbar-brand" href="https://docs.fedoraproject.org/"><img alt="Fedora Documentation" src="../../../master/_images/fedora.svg"></a>
</div>
</div>
</div>
<div class="container">
<p class="toggle-nav visible-xs pull-left">
<button class="btn btn-default btn-sm" type="button" data-toggle="offcanvas">Toggle nav</button>
</p>
<ol class="breadcrumb">
<li class="sitename">
<a href="../../../index.html">Home</a>
</li>
<li class="hidden-xs active">
<a href="../../en-US/index.html">Defensive Coding Guide </a>
</li>
<li class="hidden-xs active">
<a href="../../en-US/index.html">Defensive Coding Guide</a>
</li>
<li class="hidden-xs active"><a href="../../en-US/tasks/Tasks-Library_Design.html">Specific Programming Tasks</a></li>
<li class="hidden-xs active">
File System Manipulation
</li>
</ol>
<div class="row row-offcanvas row-offcanvas-left">
<div class="col-xs-8 col-sm-3 col-md-3 sidebar sidebar-offcanvas">
<ul class="nav nav-sidebar">
<li class="nav-header">
<a class="" href="#" data-toggle="collapse" data-target="#topicGroup0">
<span id="tgSpan0" class="fa fa-angle-down"></span>Defensive Coding Guide
</a>
<ul id="topicGroup0" class="collapse in list-unstyled">
<li><a class="" href="../../en-US/index.html">Book Information</a></li>
<li class="nav-header">
<a class="" href="#" data-toggle="collapse" data-target="#topicSubGroup-0-1">
<span id="sgSpan-0-1" class="fa fa-caret-right"></span>&nbsp;Programming Languages
</a>
<ul id="topicSubGroup-0-1" class="nav-tertiary list-unstyled collapse">
<li><a class="" href="../../en-US/programming-languages/C.html">The C Programming Language</a></li>
<li><a class="" href="../../en-US/programming-languages/CXX.html">The C++ Programming&nbsp;Language</a></li>
<li><a class="" href="../../en-US/programming-languages/Java.html">The Java Programming Language</a></li>
<li><a class="" href="../../en-US/programming-languages/Python.html">The Python Programming Language</a></li>
<li><a class="" href="../../en-US/programming-languages/Shell.html">Shell Programming and bash</a></li>
<li><a class="" href="../../en-US/programming-languages/Go.html">The Go Programming Language</a></li>
<li><a class="" href="../../en-US/programming-languages/Vala.html">The Vala Programming Language</a></li>
</ul>
</li>
<li class="nav-header">
<a class="" href="#" data-toggle="collapse" data-target="#topicSubGroup-0-2">
<span id="sgSpan-0-2" class="fa fa-caret-down"></span>&nbsp;Specific Programming Tasks
</a>
<ul id="topicSubGroup-0-2" class="nav-tertiary list-unstyled collapse in">
<li><a class="" href="../../en-US/tasks/Tasks-Library_Design.html">Library Design</a></li>
<li><a class="" href="../../en-US/tasks/Tasks-Descriptors.html">File Descriptor Management</a></li>
<li><a class=" active" href="../../en-US/tasks/Tasks-File_System.html">File System Manipulation</a></li>
<li><a class="" href="../../en-US/tasks/Tasks-Temporary_Files.html">Temporary Files</a></li>
<li><a class="" href="../../en-US/tasks/Tasks-Processes.html">Processes</a></li>
<li><a class="" href="../../en-US/tasks/Tasks-Serialization.html">Serialization and Deserialization</a></li>
<li><a class="" href="../../en-US/tasks/Tasks-Cryptography.html">Cryptography</a></li>
<li><a class="" href="../../en-US/tasks/Tasks-Packaging.html">RPM Packaging</a></li>
</ul>
</li>
<li class="nav-header">
<a class="" href="#" data-toggle="collapse" data-target="#topicSubGroup-0-3">
<span id="sgSpan-0-3" class="fa fa-caret-right"></span>&nbsp;Implementing Security Features
</a>
<ul id="topicSubGroup-0-3" class="nav-tertiary list-unstyled collapse">
<li><a class="" href="../../en-US/features/Features-Authentication.html">Authentication and Authorization</a></li>
<li><a class="" href="../../en-US/features/Features-TLS.html">Transport Layer Security (TLS)</a></li>
<li><a class="" href="../../en-US/features/Features-HSM.html">Hardware Security Modules and Smart Cards</a></li>
</ul>
</li>
<li><a class="" href="../../en-US/Revision_History.html">Revision History</a></li>
</ul>
</li>
</ul>
</div>
<div class="col-xs-12 col-sm-9 col-md-9 main">
<div class="page-header">
<h2>File System Manipulation</h2>
</div>
<div id="preamble">
<div class="sectionbody">
<div class="paragraph">
<p>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.</p>
</div>
<div class="paragraph">
<p>Temporary files are covered in their own chapter, <a href="#chap-Defensive_Coding-Tasks-Temporary_Files">[chap-Defensive_Coding-Tasks-Temporary_Files]</a>.</p>
</div>
</div>
</div>
<div class="sect1">
<h2 id="sect-Defensive_Coding-Tasks-File_System-Unowned"><a class="anchor" href="#sect-Defensive_Coding-Tasks-File_System-Unowned"></a>Working with Files and Directories Owned by Other Users</h2>
<div class="sectionbody">
<div class="paragraph">
<p>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
<a href="#sect-Defensive_Coding-Tasks-File_System-Foreign">Accessing the File System as a Different User</a>.</p>
</div>
<div class="paragraph">
<p>Accessing files across trust boundaries faces several
challenges, particularly if an entire directory tree is being
traversed:</p>
</div>
<div class="olist arabic">
<ol class="arabic">
<li>
<p>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 <code>readdir</code>.</p>
</li>
<li>
<p>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 <code>O_NONBLOCK</code> flag is specified.</p>
</li>
<li>
<p>Hard links and symbolic links can redirect the effect of
file system operations in unexpected ways. The
<code>O_NOFOLLOW</code> and
<code>AT_SYMLINK_NOFOLLOW</code> variants of system
calls only affected final path name component.</p>
</li>
<li>
<p>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.</p>
</li>
</ol>
</div>
<div class="paragraph">
<p>Files should always be created with the
<code>O_CREAT</code> and <code>O_EXCL</code> 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 <code>000</code> if
possible, and adjust it afterwards with
<code>fchmod</code>.</p>
</div>
<div class="paragraph">
<p>To avoid issues related to symbolic links and directory tree
restructuring, the “<code>at</code>” variants of system
calls have to be used (that is, functions like
<code>openat</code>, <code>fchownat</code>,
<code>fchmodat</code>, and
<code>unlinkat</code>, together with
<code>O_NOFOLLOW</code> or
<code>AT_SYMLINK_NOFOLLOW</code>). 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
<code>opendirat</code> function can be emulated with
<code>openat</code> (with an
<code>O_DIRECTORY</code> flag, to avoid opening special
files with side effects), followed by
<code>fdopendir</code>.</p>
</div>
<div class="paragraph">
<p>If the “<code>at</code>” 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.)
<code>fchdir</code> 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 “<code>at</code>”-based
approach. <code>chdir("&#8230;&#8203;")</code> is unsafe because it
might ascend outside the intended directory tree.</p>
</div>
<div class="paragraph">
<p>This “<code>at</code>” function emulation is currently
required when manipulating extended attributes. In this case,
the <code>lsetxattr</code> function can be used, with a
relative path name consisting of a single component. This also
applies to SELinux contexts and the
<code>lsetfilecon</code> function.</p>
</div>
<div class="paragraph">
<p>Currently, it is not possible to avoid opening special files
<strong>and</strong> 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.)
<code>fchmodat</code> and <code>fchownat</code>
affect files whose link count is greater than one. But opening
the files, checking that the link count is one with
<code>fstat</code>, and using
<code>fchmod</code> and <code>fchown</code> 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.</p>
</div>
<div class="paragraph">
<p>Similarly, when just reading a directory owned by an untrusted
user, it is currently impossible to reliably avoid opening
special files.</p>
</div>
<div class="paragraph">
<p>There is no workaround against the instability of the file list
returned by <code>readdir</code>. Concurrent
modification of the directory can result in a list of files
being returned which never actually existed on disk.</p>
</div>
<div class="paragraph">
<p>Hard links and symbolic links can be safely deleted using
<code>unlinkat</code> without further checks because
deletion only affects the name within the directory tree being
processed.</p>
</div>
</div>
</div>
<div class="sect1">
<h2 id="sect-Defensive_Coding-Tasks-File_System-Foreign"><a class="anchor" href="#sect-Defensive_Coding-Tasks-File_System-Foreign"></a>Accessing the File System as a Different User</h2>
<div class="sectionbody">
<div class="paragraph">
<p>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 <a href="#sect-Defensive_Coding-Tasks-File_System-Foreign">Accessing the File System as a Different User</a>.</p>
</div>
<div class="paragraph">
<p>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 <code>stat</code> system call.</p>
</div>
<div class="paragraph">
<p>An existing process could change its user and group ID using
<code>setfsuid</code> and <code>setfsgid</code>.
(These functions are preferred over <code>seteuid</code>
and <code>setegid</code> 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.</p>
</div>
<div class="paragraph">
<p>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.</p>
</div>
</div>
</div>
<div class="sect1">
<h2 id="sect-Defensive_Coding-Tasks-File_System-Limits"><a class="anchor" href="#sect-Defensive_Coding-Tasks-File_System-Limits"></a>File System Limits</h2>
<div class="sectionbody">
<div class="paragraph">
<p>For historical reasons, there are preprocessor constants such as
<code>PATH_MAX</code>, <code>NAME_MAX</code>.
However, on most systems, the length of canonical path names
(absolute path names with all symbolic links resolved, as
returned by <code>realpath</code> or
<code>canonicalize_file_name</code>) can exceed
<code>PATH_MAX</code> bytes, and individual file name
components can be longer than <code>NAME_MAX</code>. This
is also true of the <code>_PC_PATH_MAX</code> and
<code>_PC_NAME_MAX</code> values returned by
<code>pathconf</code>, and the
<code>f_namemax</code> member of <code>struct
statvfs</code>. Therefore, these constants should not be
used. This is also reason why the
<code>readdir_r</code> should never be used (instead,
use <code>readdir</code>).</p>
</div>
<div class="paragraph">
<p>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.</p>
</div>
</div>
</div>
<div class="sect1">
<h2 id="sect-Defensive_Coding-Tasks-File_System-Features"><a class="anchor" href="#sect-Defensive_Coding-Tasks-File_System-Features"></a>File system features</h2>
<div class="sectionbody">
<div class="paragraph">
<p>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.</p>
</div>
<div class="ulist">
<ul>
<li>
<p>Some file systems are case-insensitive. Most should be
case-preserving, though.</p>
</li>
<li>
<p>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.</p>
</li>
<li>
<p>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
<code>readdir</code> might still result in a
different byte sequence.</p>
</li>
<li>
<p>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.</p>
</li>
<li>
<p>Non-regular files (device nodes, FIFOs) are not generally
available.</p>
</li>
<li>
<p>Only on some file systems, files can have holes, that is,
not all of their contents is backed by disk storage.</p>
</li>
<li>
<p><code>ioctl</code> support (even fairly generic
functionality such as <code>FIEMAP</code> for
discovering physical file layout and holes) is
file-system-specific.</p>
</li>
<li>
<p>Not all file systems support extended attributes, ACLs and
SELinux metadata. Size and naming restriction on extended
attributes vary.</p>
</li>
<li>
<p>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.</p>
</li>
<li>
<p>Renaming (or moving) files using <code>rename</code>
can fail (even when <code>stat</code> 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.</p>
</li>
<li>
<p>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.</p>
</li>
<li>
<p>Resolution of time stamps varies from two seconds to
nanoseconds. Not all time stamps are available on all file
systems. File creation time (<strong>birth
time</strong>) is not exposed over the
<code>stat</code>/<code>fstat</code>
interface, even if stored by the file system.</p>
</li>
</ul>
</div>
</div>
</div>
<div class="sect1">
<h2 id="sect-Defensive_Coding-Tasks-File_System-Free_Space"><a class="anchor" href="#sect-Defensive_Coding-Tasks-File_System-Free_Space"></a>Checking Free Space</h2>
<div class="sectionbody">
<div class="paragraph">
<p>The <code>statvfs</code> and
<code>fstatvfs</code> functions allow programs to
examine the number of available blocks and inodes, through the
members <code>f_bfree</code>, <code>f_bavail</code>,
<code>f_ffree</code>, and <code>f_favail</code> of
<code>struct statvfs</code>. Some file systems return
fictional values in the <code>f_ffree</code> and
<code>f_favail</code> 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 <code>f_bfree</code> field should be
reasonably accurate, though.</p>
</div>
</div>
</div>
</div>
</div>
</div>
<div id="bottom" class="text-muted py-3" >
<div class="foot">
<div class="container">
<div class="row footerlinks">
<div class="col-sm-3 col-xs-6 widget">
<h3 class="widget-title">About</h3>
<div class="widget-body">
<dl>
<dd><a href="https://fedoraproject.org/wiki/Overview">About Fedora</a></dd>
<dd><a href="https://getfedora.org/en/sponsors">Sponsors</a></dd>
<dd><a href="https://fedoramagazine.org">Fedora Magazine</a></dd>
<dd><a href="https://fedoraproject.org/wiki/Legal:Main#Legal">Legal</a></dd>
</dl>
<ul class="list-inline">
<li>
<a href="https://www.facebook.com/TheFedoraProject" class="btn-social btn-outline"><i class="fa fa-fw fa-facebook"></i></a>
</li>
<li>
<a href="https://plus.google.com/112917221531140868607" class="btn-social btn-outline"><i class="fa fa-fw fa-google-plus"></i></a>
</li>
<li>
<a href="https://twitter.com/fedora" class="btn-social btn-outline"><i class="fa fa-fw fa-twitter"></i></a>
</li>
</ul>
</div>
</div>
<div class="col-sm-3 col-xs-6 widget">
<h3 class="widget-title uppercase">Download</h3>
<div class="widget-body">
<dl>
<dd><a href="https://getfedora.org/en/workstation/download">Get Fedora Workstation</a></dd>
<dd><a href="https://getfedora.org/en/server/download">Get Fedora Server</a></dd>
<dd><a href="https://getfedora.org/en/atomic/download">Get Fedora Atomic</a></dd>
<dd><a href="https://spins.fedoraproject.org">Fedora Spins</a></dd>
<dd><a href="https://labs.fedoraproject.org">Fedora Labs</a></dd>
<dd><a href="https://arm.fedoraproject.org">Fedora ARM<span class="sup">&reg;</span></a></dd>
<dd><a href="https://alt.fedoraproject.org/">Alternative Downloads</a></dd>
</dl>
</div>
</div>
<div class="col-sm-3 col-xs-6 widget">
<h3 class="widget-title">Support</h3>
<div class="widget-body">
<dl>
<dd><a href="https://fedoraproject.org/wiki/Communicating_and_getting_help">Get Help</a></dd>
<dd><a href="https://ask.fedoraproject.org/">Ask Fedora</a></dd>
<dd><a href="https://fedoraproject.org/wiki/Common_F27_bugs">Common Bugs</a></dd>
<dd><a href="https://developer.fedoraproject.org/">Fedora Developer Portal</a></dd>
<dd><a href="https://docs.fedoraproject.org/f27/install-guide/index.html">Installation Guide</a></dd>
</dl>
</div>
</div>
<div class="col-sm-3 col-xs-6 widget">
<h3 class="widget-title">Join</h3>
<div class="widget-body">
<dl>
<dd><a href="https://fedoraproject.org/wiki/Join">Join Fedora</a></dd>
<dd><a href="http://fedoraplanet.org">Planet Fedora</a></dd>
<dd><a href="https://fedoraproject.org/wiki/SIGs">Fedora SIGs</a></dd>
<dd><a href="https://admin.fedoraproject.org/accounts/">Fedora Account System</a></dd>
<dd><a href="https://fedoracommunity.org/">Fedora Community</a></dd>
</dl>
</div>
</div>
</div> <!-- /row of widgets -->
<div class="row">
<div class="col-md-2">
<div class="widget-body">
<a href="https://www.redhat.com/"><img class="rh-logo" src="../../../master/_images/redhat-logo.png" alt="Red Hat Logo" /></a>
</div>
</div>
<div class="col-md-7">
<div class="widget-body">
<p class="sponsor">Fedora is sponsored by Red Hat.</p>
<p class="sponsor"><a href="https://www.redhat.com/en/technologies/linux-platforms/articles/relationship-between-fedora-and-rhel">Learn more about the relationship between Red Hat and Fedora &raquo;</a></p>
<p class="copy">&copy; 2017 Red Hat, Inc. and others. Please send any comments or corrections to the <a href="https://pagure.io/fedora-docs/docs-fp-o">documentation team</a></p>
</div>
</div>
</div> <!-- /row of widgets -->
</div>
</div>
</div>
<!-- jQuery (necessary for Bootstrap's JavaScript plugins) -->
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>
<!-- Latest compiled and minified JavaScript -->
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/js/bootstrap.min.js"></script>
<script src="../../../master/_javascripts/bootstrap-offcanvas.js" type="text/javascript"></script>
<script type="text/javascript">
/*<![CDATA[*/
$(document).ready(function() {
$("[id^='topicGroup']").on('show.bs.collapse', function (event) {
if (!($(event.target).attr('id').match(/^topicSubGroup/))) {
$(this).parent().find("[id^='tgSpan']").toggleClass("fa-angle-right fa-angle-down");
}
});
$("[id^='topicGroup']").on('hide.bs.collapse', function (event) {
if (!($(event.target).attr('id').match(/^topicSubGroup/))) {
$(this).parent().find("[id^='tgSpan']").toggleClass("fa-angle-right fa-angle-down");
}
});
$("[id^='topicSubGroup']").on('show.bs.collapse', function () {
$(this).parent().find("[id^='sgSpan']").toggleClass("fa-caret-right fa-caret-down");
});
$("[id^='topicSubGroup']").on('hide.bs.collapse', function () {
$(this).parent().find("[id^='sgSpan']").toggleClass("fa-caret-right fa-caret-down");
});
});
/*]]>*/
</script>
</body>
</html>

View file

@ -1,425 +0,0 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta content="IE=edge" http-equiv="X-UA-Compatible">
<meta content="width=device-width, initial-scale=1.0" name="viewport">
<title>Defensive Coding Guide | Defensive Coding Guide | Specific Programming Tasks | Library Design</title>
<!-- Bootstrap -->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css">
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap-theme.min.css">
<!-- Overpass Font -->
<link rel="stylesheet" href="https://overpass-30e2.kxcdn.com/overpass.css">
<link href="../../../master/_stylesheets/asciibinder.css" rel="stylesheet" />
<!-- HTML5 shim and Respond.js for IE8 support of HTML5 elements and media queries -->
<!-- WARNING: Respond.js doesn't work if you view the page via file:// -->
<!--[if lt IE 9]>
<script src="https://oss.maxcdn.com/html5shiv/3.7.2/html5shiv.min.js"></script>
<script src="https://oss.maxcdn.com/respond/1.4.2/respond.min.js"></script>
<![endif]-->
<link href="../../../master/_images/favicon32x32.png" rel="shortcut icon" type="text/css">
<!--[if IE]><link rel="shortcut icon" href="../../../master/_images/favicon.ico"><![endif]-->
<meta content="AsciiBinder" name="application-name">
</head>
<body>
<div class="navbar navbar-default" role="navigation">
<div class="container-fluid">
<div class="navbar-header">
<a class="navbar-brand" href="https://docs.fedoraproject.org/"><img alt="Fedora Documentation" src="../../../master/_images/fedora.svg"></a>
</div>
</div>
</div>
<div class="container">
<p class="toggle-nav visible-xs pull-left">
<button class="btn btn-default btn-sm" type="button" data-toggle="offcanvas">Toggle nav</button>
</p>
<ol class="breadcrumb">
<li class="sitename">
<a href="../../../index.html">Home</a>
</li>
<li class="hidden-xs active">
<a href="../../en-US/index.html">Defensive Coding Guide </a>
</li>
<li class="hidden-xs active">
<a href="../../en-US/index.html">Defensive Coding Guide</a>
</li>
<li class="hidden-xs active"><a href="../../en-US/tasks/Tasks-Library_Design.html">Specific Programming Tasks</a></li>
<li class="hidden-xs active">
Library Design
</li>
</ol>
<div class="row row-offcanvas row-offcanvas-left">
<div class="col-xs-8 col-sm-3 col-md-3 sidebar sidebar-offcanvas">
<ul class="nav nav-sidebar">
<li class="nav-header">
<a class="" href="#" data-toggle="collapse" data-target="#topicGroup0">
<span id="tgSpan0" class="fa fa-angle-down"></span>Defensive Coding Guide
</a>
<ul id="topicGroup0" class="collapse in list-unstyled">
<li><a class="" href="../../en-US/index.html">Book Information</a></li>
<li class="nav-header">
<a class="" href="#" data-toggle="collapse" data-target="#topicSubGroup-0-1">
<span id="sgSpan-0-1" class="fa fa-caret-right"></span>&nbsp;Programming Languages
</a>
<ul id="topicSubGroup-0-1" class="nav-tertiary list-unstyled collapse">
<li><a class="" href="../../en-US/programming-languages/C.html">The C Programming Language</a></li>
<li><a class="" href="../../en-US/programming-languages/CXX.html">The C++ Programming&nbsp;Language</a></li>
<li><a class="" href="../../en-US/programming-languages/Java.html">The Java Programming Language</a></li>
<li><a class="" href="../../en-US/programming-languages/Python.html">The Python Programming Language</a></li>
<li><a class="" href="../../en-US/programming-languages/Shell.html">Shell Programming and bash</a></li>
<li><a class="" href="../../en-US/programming-languages/Go.html">The Go Programming Language</a></li>
<li><a class="" href="../../en-US/programming-languages/Vala.html">The Vala Programming Language</a></li>
</ul>
</li>
<li class="nav-header">
<a class="" href="#" data-toggle="collapse" data-target="#topicSubGroup-0-2">
<span id="sgSpan-0-2" class="fa fa-caret-down"></span>&nbsp;Specific Programming Tasks
</a>
<ul id="topicSubGroup-0-2" class="nav-tertiary list-unstyled collapse in">
<li><a class=" active" href="../../en-US/tasks/Tasks-Library_Design.html">Library Design</a></li>
<li><a class="" href="../../en-US/tasks/Tasks-Descriptors.html">File Descriptor Management</a></li>
<li><a class="" href="../../en-US/tasks/Tasks-File_System.html">File System Manipulation</a></li>
<li><a class="" href="../../en-US/tasks/Tasks-Temporary_Files.html">Temporary Files</a></li>
<li><a class="" href="../../en-US/tasks/Tasks-Processes.html">Processes</a></li>
<li><a class="" href="../../en-US/tasks/Tasks-Serialization.html">Serialization and Deserialization</a></li>
<li><a class="" href="../../en-US/tasks/Tasks-Cryptography.html">Cryptography</a></li>
<li><a class="" href="../../en-US/tasks/Tasks-Packaging.html">RPM Packaging</a></li>
</ul>
</li>
<li class="nav-header">
<a class="" href="#" data-toggle="collapse" data-target="#topicSubGroup-0-3">
<span id="sgSpan-0-3" class="fa fa-caret-right"></span>&nbsp;Implementing Security Features
</a>
<ul id="topicSubGroup-0-3" class="nav-tertiary list-unstyled collapse">
<li><a class="" href="../../en-US/features/Features-Authentication.html">Authentication and Authorization</a></li>
<li><a class="" href="../../en-US/features/Features-TLS.html">Transport Layer Security (TLS)</a></li>
<li><a class="" href="../../en-US/features/Features-HSM.html">Hardware Security Modules and Smart Cards</a></li>
</ul>
</li>
<li><a class="" href="../../en-US/Revision_History.html">Revision History</a></li>
</ul>
</li>
</ul>
</div>
<div class="col-xs-12 col-sm-9 col-md-9 main">
<div class="page-header">
<h2>Library Design</h2>
</div>
<div id="preamble">
<div class="sectionbody">
<div class="paragraph">
<p>Through this section, the term <strong>client code</strong>
refers to applications and other libraries using the library.</p>
</div>
</div>
</div>
<div class="sect1">
<h2 id="state-management"><a class="anchor" href="#state-management"></a>State Management</h2>
<div class="sectionbody">
<div class="sect2">
<h3 id="global-state"><a class="anchor" href="#global-state"></a>Global State</h3>
<div class="paragraph">
<p>Global state should be avoided.</p>
</div>
<div class="paragraph">
<p>If this is impossible, the global state must be protected with
a lock. For C/C++, you can use the
<code>pthread_mutex_lock</code>
and <code>pthread_mutex_unlock</code>
functions without linking against <code>-lpthread</code>
because the system provides stubs for non-threaded processes.</p>
</div>
<div class="paragraph">
<p>For compatibility with <code>fork</code>, these locks
should be acquired and released in helpers registered with
<code>pthread_atfork</code>. This function is not
available without <code>-lpthread</code>, so you need to
use <code>dlsym</code> or a weak symbol to obtain its
address.</p>
</div>
<div class="paragraph">
<p>If you need <code>fork</code> protection for other
reasons, you should store the process ID and compare it to the
value returned by <code>getpid</code> each time you
access the global state. (<code>getpid</code> 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.)</p>
</div>
</div>
<div class="sect2">
<h3 id="handles"><a class="anchor" href="#handles"></a>Handles</h3>
<div class="paragraph">
<p>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 <code>struct</code>. In C++,
the handle can be a pointer to an abstract base class, or it
can be hidden using the pointer-to-implementation idiom.</p>
</div>
<div class="paragraph">
<p>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.)</p>
</div>
<div class="paragraph">
<p>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.</p>
</div>
<div class="paragraph">
<p>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.</p>
</div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="object-orientation"><a class="anchor" href="#object-orientation"></a>Object Orientation</h2>
<div class="sectionbody">
<div class="paragraph">
<p>Classes should be either designed as base classes, or it should
be impossible to use them as base classes (like
<code>final</code> 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.</p>
</div>
<div class="paragraph">
<p>Virtual member functions can be used as callbacks. See
<a href="#sect-Defensive_Coding-Tasks-Library_Design-Callbacks">Callbacks</a>
for some of the challenges involved.</p>
</div>
</div>
</div>
<div class="sect1">
<h2 id="sect-Defensive_Coding-Tasks-Library_Design-Callbacks"><a class="anchor" href="#sect-Defensive_Coding-Tasks-Library_Design-Callbacks"></a>Callbacks</h2>
<div class="sectionbody">
<div class="paragraph">
<p>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.</p>
</div>
<div class="paragraph">
<p>If callbacks are unavoidable, some guidelines for them follow.</p>
</div>
<div class="paragraph">
<p>In modern C++ code, <code>std::function</code> objects
should be used for callbacks.</p>
</div>
<div class="paragraph">
<p>In older C++ code and in C code, all callbacks must have an
additional closure parameter of type <code>void *</code>,
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.</p>
</div>
<div class="paragraph">
<p>Callbacks can throw exceptions or call
<code>longjmp</code>. 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.)</p>
</div>
<div class="paragraph">
<p>The presence of callbacks raises the question if functions
provided by the library are <strong>reentrant</strong>.
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.</p>
</div>
</div>
</div>
<div class="sect1">
<h2 id="process-attributes"><a class="anchor" href="#process-attributes"></a>Process Attributes</h2>
<div class="sectionbody">
<div class="paragraph">
<p>Several attributes are global and affect all code in the
process, not just the library that manipulates them.</p>
</div>
<div class="ulist">
<ul>
<li>
<p>environment variables
(see <a href="#sect-Defensive_Coding-Tasks-secure_getenv">[sect-Defensive_Coding-Tasks-secure_getenv]</a>)</p>
</li>
<li>
<p>umask</p>
</li>
<li>
<p>user IDs, group IDs and capabilities</p>
</li>
<li>
<p>current working directory</p>
</li>
<li>
<p>signal handlers, signal masks and signal delivery</p>
</li>
<li>
<p>file locks (especially <code>fcntl</code> locks
behave in surprising ways, not just in a multi-threaded
environment)</p>
</li>
</ul>
</div>
<div class="paragraph">
<p>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.</p>
</div>
<div class="paragraph">
<p>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.</p>
</div>
</div>
</div>
</div>
</div>
</div>
<div id="bottom" class="text-muted py-3" >
<div class="foot">
<div class="container">
<div class="row footerlinks">
<div class="col-sm-3 col-xs-6 widget">
<h3 class="widget-title">About</h3>
<div class="widget-body">
<dl>
<dd><a href="https://fedoraproject.org/wiki/Overview">About Fedora</a></dd>
<dd><a href="https://getfedora.org/en/sponsors">Sponsors</a></dd>
<dd><a href="https://fedoramagazine.org">Fedora Magazine</a></dd>
<dd><a href="https://fedoraproject.org/wiki/Legal:Main#Legal">Legal</a></dd>
</dl>
<ul class="list-inline">
<li>
<a href="https://www.facebook.com/TheFedoraProject" class="btn-social btn-outline"><i class="fa fa-fw fa-facebook"></i></a>
</li>
<li>
<a href="https://plus.google.com/112917221531140868607" class="btn-social btn-outline"><i class="fa fa-fw fa-google-plus"></i></a>
</li>
<li>
<a href="https://twitter.com/fedora" class="btn-social btn-outline"><i class="fa fa-fw fa-twitter"></i></a>
</li>
</ul>
</div>
</div>
<div class="col-sm-3 col-xs-6 widget">
<h3 class="widget-title uppercase">Download</h3>
<div class="widget-body">
<dl>
<dd><a href="https://getfedora.org/en/workstation/download">Get Fedora Workstation</a></dd>
<dd><a href="https://getfedora.org/en/server/download">Get Fedora Server</a></dd>
<dd><a href="https://getfedora.org/en/atomic/download">Get Fedora Atomic</a></dd>
<dd><a href="https://spins.fedoraproject.org">Fedora Spins</a></dd>
<dd><a href="https://labs.fedoraproject.org">Fedora Labs</a></dd>
<dd><a href="https://arm.fedoraproject.org">Fedora ARM<span class="sup">&reg;</span></a></dd>
<dd><a href="https://alt.fedoraproject.org/">Alternative Downloads</a></dd>
</dl>
</div>
</div>
<div class="col-sm-3 col-xs-6 widget">
<h3 class="widget-title">Support</h3>
<div class="widget-body">
<dl>
<dd><a href="https://fedoraproject.org/wiki/Communicating_and_getting_help">Get Help</a></dd>
<dd><a href="https://ask.fedoraproject.org/">Ask Fedora</a></dd>
<dd><a href="https://fedoraproject.org/wiki/Common_F27_bugs">Common Bugs</a></dd>
<dd><a href="https://developer.fedoraproject.org/">Fedora Developer Portal</a></dd>
<dd><a href="https://docs.fedoraproject.org/f27/install-guide/index.html">Installation Guide</a></dd>
</dl>
</div>
</div>
<div class="col-sm-3 col-xs-6 widget">
<h3 class="widget-title">Join</h3>
<div class="widget-body">
<dl>
<dd><a href="https://fedoraproject.org/wiki/Join">Join Fedora</a></dd>
<dd><a href="http://fedoraplanet.org">Planet Fedora</a></dd>
<dd><a href="https://fedoraproject.org/wiki/SIGs">Fedora SIGs</a></dd>
<dd><a href="https://admin.fedoraproject.org/accounts/">Fedora Account System</a></dd>
<dd><a href="https://fedoracommunity.org/">Fedora Community</a></dd>
</dl>
</div>
</div>
</div> <!-- /row of widgets -->
<div class="row">
<div class="col-md-2">
<div class="widget-body">
<a href="https://www.redhat.com/"><img class="rh-logo" src="../../../master/_images/redhat-logo.png" alt="Red Hat Logo" /></a>
</div>
</div>
<div class="col-md-7">
<div class="widget-body">
<p class="sponsor">Fedora is sponsored by Red Hat.</p>
<p class="sponsor"><a href="https://www.redhat.com/en/technologies/linux-platforms/articles/relationship-between-fedora-and-rhel">Learn more about the relationship between Red Hat and Fedora &raquo;</a></p>
<p class="copy">&copy; 2017 Red Hat, Inc. and others. Please send any comments or corrections to the <a href="https://pagure.io/fedora-docs/docs-fp-o">documentation team</a></p>
</div>
</div>
</div> <!-- /row of widgets -->
</div>
</div>
</div>
<!-- jQuery (necessary for Bootstrap's JavaScript plugins) -->
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>
<!-- Latest compiled and minified JavaScript -->
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/js/bootstrap.min.js"></script>
<script src="../../../master/_javascripts/bootstrap-offcanvas.js" type="text/javascript"></script>
<script type="text/javascript">
/*<![CDATA[*/
$(document).ready(function() {
$("[id^='topicGroup']").on('show.bs.collapse', function (event) {
if (!($(event.target).attr('id').match(/^topicSubGroup/))) {
$(this).parent().find("[id^='tgSpan']").toggleClass("fa-angle-right fa-angle-down");
}
});
$("[id^='topicGroup']").on('hide.bs.collapse', function (event) {
if (!($(event.target).attr('id').match(/^topicSubGroup/))) {
$(this).parent().find("[id^='tgSpan']").toggleClass("fa-angle-right fa-angle-down");
}
});
$("[id^='topicSubGroup']").on('show.bs.collapse', function () {
$(this).parent().find("[id^='sgSpan']").toggleClass("fa-caret-right fa-caret-down");
});
$("[id^='topicSubGroup']").on('hide.bs.collapse', function () {
$(this).parent().find("[id^='sgSpan']").toggleClass("fa-caret-right fa-caret-down");
});
});
/*]]>*/
</script>
</body>
</html>

View file

@ -1,438 +0,0 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta content="IE=edge" http-equiv="X-UA-Compatible">
<meta content="width=device-width, initial-scale=1.0" name="viewport">
<title>Defensive Coding Guide | Defensive Coding Guide | Specific Programming Tasks | RPM Packaging</title>
<!-- Bootstrap -->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css">
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap-theme.min.css">
<!-- Overpass Font -->
<link rel="stylesheet" href="https://overpass-30e2.kxcdn.com/overpass.css">
<link href="../../../master/_stylesheets/asciibinder.css" rel="stylesheet" />
<!-- HTML5 shim and Respond.js for IE8 support of HTML5 elements and media queries -->
<!-- WARNING: Respond.js doesn't work if you view the page via file:// -->
<!--[if lt IE 9]>
<script src="https://oss.maxcdn.com/html5shiv/3.7.2/html5shiv.min.js"></script>
<script src="https://oss.maxcdn.com/respond/1.4.2/respond.min.js"></script>
<![endif]-->
<link href="../../../master/_images/favicon32x32.png" rel="shortcut icon" type="text/css">
<!--[if IE]><link rel="shortcut icon" href="../../../master/_images/favicon.ico"><![endif]-->
<meta content="AsciiBinder" name="application-name">
</head>
<body>
<div class="navbar navbar-default" role="navigation">
<div class="container-fluid">
<div class="navbar-header">
<a class="navbar-brand" href="https://docs.fedoraproject.org/"><img alt="Fedora Documentation" src="../../../master/_images/fedora.svg"></a>
</div>
</div>
</div>
<div class="container">
<p class="toggle-nav visible-xs pull-left">
<button class="btn btn-default btn-sm" type="button" data-toggle="offcanvas">Toggle nav</button>
</p>
<ol class="breadcrumb">
<li class="sitename">
<a href="../../../index.html">Home</a>
</li>
<li class="hidden-xs active">
<a href="../../en-US/index.html">Defensive Coding Guide </a>
</li>
<li class="hidden-xs active">
<a href="../../en-US/index.html">Defensive Coding Guide</a>
</li>
<li class="hidden-xs active"><a href="../../en-US/tasks/Tasks-Library_Design.html">Specific Programming Tasks</a></li>
<li class="hidden-xs active">
RPM Packaging
</li>
</ol>
<div class="row row-offcanvas row-offcanvas-left">
<div class="col-xs-8 col-sm-3 col-md-3 sidebar sidebar-offcanvas">
<ul class="nav nav-sidebar">
<li class="nav-header">
<a class="" href="#" data-toggle="collapse" data-target="#topicGroup0">
<span id="tgSpan0" class="fa fa-angle-down"></span>Defensive Coding Guide
</a>
<ul id="topicGroup0" class="collapse in list-unstyled">
<li><a class="" href="../../en-US/index.html">Book Information</a></li>
<li class="nav-header">
<a class="" href="#" data-toggle="collapse" data-target="#topicSubGroup-0-1">
<span id="sgSpan-0-1" class="fa fa-caret-right"></span>&nbsp;Programming Languages
</a>
<ul id="topicSubGroup-0-1" class="nav-tertiary list-unstyled collapse">
<li><a class="" href="../../en-US/programming-languages/C.html">The C Programming Language</a></li>
<li><a class="" href="../../en-US/programming-languages/CXX.html">The C++ Programming&nbsp;Language</a></li>
<li><a class="" href="../../en-US/programming-languages/Java.html">The Java Programming Language</a></li>
<li><a class="" href="../../en-US/programming-languages/Python.html">The Python Programming Language</a></li>
<li><a class="" href="../../en-US/programming-languages/Shell.html">Shell Programming and bash</a></li>
<li><a class="" href="../../en-US/programming-languages/Go.html">The Go Programming Language</a></li>
<li><a class="" href="../../en-US/programming-languages/Vala.html">The Vala Programming Language</a></li>
</ul>
</li>
<li class="nav-header">
<a class="" href="#" data-toggle="collapse" data-target="#topicSubGroup-0-2">
<span id="sgSpan-0-2" class="fa fa-caret-down"></span>&nbsp;Specific Programming Tasks
</a>
<ul id="topicSubGroup-0-2" class="nav-tertiary list-unstyled collapse in">
<li><a class="" href="../../en-US/tasks/Tasks-Library_Design.html">Library Design</a></li>
<li><a class="" href="../../en-US/tasks/Tasks-Descriptors.html">File Descriptor Management</a></li>
<li><a class="" href="../../en-US/tasks/Tasks-File_System.html">File System Manipulation</a></li>
<li><a class="" href="../../en-US/tasks/Tasks-Temporary_Files.html">Temporary Files</a></li>
<li><a class="" href="../../en-US/tasks/Tasks-Processes.html">Processes</a></li>
<li><a class="" href="../../en-US/tasks/Tasks-Serialization.html">Serialization and Deserialization</a></li>
<li><a class="" href="../../en-US/tasks/Tasks-Cryptography.html">Cryptography</a></li>
<li><a class=" active" href="../../en-US/tasks/Tasks-Packaging.html">RPM Packaging</a></li>
</ul>
</li>
<li class="nav-header">
<a class="" href="#" data-toggle="collapse" data-target="#topicSubGroup-0-3">
<span id="sgSpan-0-3" class="fa fa-caret-right"></span>&nbsp;Implementing Security Features
</a>
<ul id="topicSubGroup-0-3" class="nav-tertiary list-unstyled collapse">
<li><a class="" href="../../en-US/features/Features-Authentication.html">Authentication and Authorization</a></li>
<li><a class="" href="../../en-US/features/Features-TLS.html">Transport Layer Security (TLS)</a></li>
<li><a class="" href="../../en-US/features/Features-HSM.html">Hardware Security Modules and Smart Cards</a></li>
</ul>
</li>
<li><a class="" href="../../en-US/Revision_History.html">Revision History</a></li>
</ul>
</li>
</ul>
</div>
<div class="col-xs-12 col-sm-9 col-md-9 main">
<div class="page-header">
<h2>RPM Packaging</h2>
</div>
<div id="preamble">
<div class="sectionbody">
<div class="paragraph">
<p>This chapter deals with security-related concerns around RPM
packaging. It has to be read in conjunction with
distribution-specific packaging guidelines.</p>
</div>
</div>
</div>
<div class="sect1">
<h2 id="sect-Defensive_Coding-Tasks-Packaging-Certificates"><a class="anchor" href="#sect-Defensive_Coding-Tasks-Packaging-Certificates"></a>Generating X.509 Self-signed Certificates during Installation</h2>
<div class="sectionbody">
<div class="paragraph">
<p>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 <a href="#sect-Defensive_Coding-Tasks-Packaging-Certificates-Service">Generating X.509 Self-signed Certificates before Service Start</a>,
and <a href="https://fedoraproject.org/wiki/Packaging:Initial_Service_Setup#Generating_Self-Signed_Certificates">Packaging:Initial Service Setup</a>.</p>
</div>
<div class="admonitionblock important">
<table>
<tr>
<td class="icon">
<i class="fa icon-important" title="Important"></i>
</td>
<td class="content">
<div class="paragraph">
<p>The way the key is generated may not be suitable for key
material of critical value. (<code class="command">openssl
genrsa</code> 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.</p>
</div>
</td>
</tr>
</table>
</div>
<div class="paragraph">
<p>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:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code data-lang="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</code></pre>
</div>
</div>
<div class="paragraph">
<p>These variables likely need adjustment based on the needs of the
package.</p>
</div>
<div class="paragraph">
<p>Typically, the file with the private key needs to be owned by
the system user which needs to read it,
<code>%{tlsuser}</code> (not <code>root</code>). In
order to avoid races, if the <strong>directory</strong>
<code>%{tlsdir}</code> is <strong>owned by the services
user</strong>, you should use the code in <a href="#ex-Defensive_Coding-Packaging-Certificates-Owned">Creating a key pair in a user-owned directory</a>.
The invocation of <strong class="application">su</strong> with the
<code class="option">-s /bin/bash</code> argument is necessary in case the
login shell for the user has been disabled.</p>
</div>
<div id="ex-Defensive_Coding-Packaging-Certificates-Owned" class="exampleblock">
<div class="title">Example 1. Creating a key pair in a user-owned directory</div>
<div class="content">
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code data-lang="bash">%post
if [ $1 -eq 1 ] ; then
if ! test -e %{tlskey} ; then
su -s /bin/bash \
-c &quot;umask 077 &amp;&amp; openssl genrsa -out %{tlskey} 2048 2&gt;/dev/null&quot; \
%{tlsuser}
fi
if ! test -e %{tlscert} ; then
cn=&quot;Automatically generated certificate for the %{tlsuser} service&quot;
req_args=&quot;-key %{tlskey} -out %{tlscert} -days 7305 -subj \&quot;/CN=$cn/\&quot;&quot;
su -s /bin/bash \
-c &quot;openssl req -new -x509 -extensions usr_cert $req_args&quot; \
%{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}</code></pre>
</div>
</div>
</div>
</div>
<div class="paragraph">
<p>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 <code>%ghost</code>), or delete the files
when the package is uninstalled (the
<code>%config(noreplace)</code> part).</p>
</div>
<div class="paragraph">
<p>If the <strong>directory</strong>
<code>%{tlsdir}</code> <strong>is owned by</strong>
<code>root</code>, use the code in <a href="#ex-Defensive_Coding-Packaging-Certificates-Unowned">Creating a key pair in a <code>root</code>-owned directory</a>.</p>
</div>
<div id="ex-Defensive_Coding-Packaging-Certificates-Unowned" class="exampleblock">
<div class="title">Example 2. Creating a key pair in a <code>root</code>-owned directory</div>
<div class="content">
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code data-lang="bash">%post
if [ $1 -eq 1 ] ; then
if ! test -e %{tlskey} ; then
(umask 077 &amp;&amp; openssl genrsa -out %{tlskey} 2048 2&gt;/dev/null)
chown %{tlsuser} %{tlskey}
fi
if ! test -e %{tlscert} ; then
cn=&quot;Automatically generated certificate for the %{tlsuser} service&quot;
openssl req -new -x509 -extensions usr_cert \
-key %{tlskey} -out %{tlscert} -days 7305 -subj &quot;/CN=$cn/&quot;
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}</code></pre>
</div>
</div>
</div>
</div>
<div class="paragraph">
<p>In order for this to work, the package which generates the keys
must require the <strong class="application">openssl</strong> package. If
the user which owns the key file is generated by a different
package, the package generating the certificate must specify a
<code>Requires(pre):</code> on the package which creates
the user. This ensures that the user account will exist when it
is needed for the <strong class="application">su</strong> or
<strong class="application">chmod</strong> invocation.</p>
</div>
</div>
</div>
<div class="sect1">
<h2 id="sect-Defensive_Coding-Tasks-Packaging-Certificates-Service"><a class="anchor" href="#sect-Defensive_Coding-Tasks-Packaging-Certificates-Service"></a>Generating X.509 Self-signed Certificates before Service Start</h2>
<div class="sectionbody">
<div class="paragraph">
<p>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 <a href="#sect-Defensive_Coding-Tasks-Packaging-Certificates">Generating X.509 Self-signed Certificates during Installation</a>)
would put the key into the image, which may or may not make
sense.</p>
</div>
<div class="admonitionblock important">
<table>
<tr>
<td class="icon">
<i class="fa icon-important" title="Important"></i>
</td>
<td class="content">
<div class="paragraph">
<p>The caveats about the way the key is generated in <a href="#sect-Defensive_Coding-Tasks-Packaging-Certificates">Generating X.509 Self-signed Certificates during Installation</a>
apply to this procedure as well.</p>
</div>
</td>
</tr>
</table>
</div>
<div class="paragraph">
<p>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
<code>random: nonblocking pool is initialized</code>, or
ensure that the application used for generating the keys
is utilizing the <code>getrandom()</code> system call.</p>
</div>
<div class="paragraph">
<p>In theory, it is also possible to use an application which reads from
<code>/dev/random</code> while generating the key
material (instead of <code>/dev/urandom</code>), 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.</p>
</div>
<div class="paragraph">
<p>The requirements for generating such keys is documented at
<a href="https://fedoraproject.org/wiki/Packaging:Initial_Service_Setup#Generating_Self-Signed_Certificates">Packaging:Initial Service Setup</a>.</p>
</div>
</div>
</div>
</div>
</div>
</div>
<div id="bottom" class="text-muted py-3" >
<div class="foot">
<div class="container">
<div class="row footerlinks">
<div class="col-sm-3 col-xs-6 widget">
<h3 class="widget-title">About</h3>
<div class="widget-body">
<dl>
<dd><a href="https://fedoraproject.org/wiki/Overview">About Fedora</a></dd>
<dd><a href="https://getfedora.org/en/sponsors">Sponsors</a></dd>
<dd><a href="https://fedoramagazine.org">Fedora Magazine</a></dd>
<dd><a href="https://fedoraproject.org/wiki/Legal:Main#Legal">Legal</a></dd>
</dl>
<ul class="list-inline">
<li>
<a href="https://www.facebook.com/TheFedoraProject" class="btn-social btn-outline"><i class="fa fa-fw fa-facebook"></i></a>
</li>
<li>
<a href="https://plus.google.com/112917221531140868607" class="btn-social btn-outline"><i class="fa fa-fw fa-google-plus"></i></a>
</li>
<li>
<a href="https://twitter.com/fedora" class="btn-social btn-outline"><i class="fa fa-fw fa-twitter"></i></a>
</li>
</ul>
</div>
</div>
<div class="col-sm-3 col-xs-6 widget">
<h3 class="widget-title uppercase">Download</h3>
<div class="widget-body">
<dl>
<dd><a href="https://getfedora.org/en/workstation/download">Get Fedora Workstation</a></dd>
<dd><a href="https://getfedora.org/en/server/download">Get Fedora Server</a></dd>
<dd><a href="https://getfedora.org/en/atomic/download">Get Fedora Atomic</a></dd>
<dd><a href="https://spins.fedoraproject.org">Fedora Spins</a></dd>
<dd><a href="https://labs.fedoraproject.org">Fedora Labs</a></dd>
<dd><a href="https://arm.fedoraproject.org">Fedora ARM<span class="sup">&reg;</span></a></dd>
<dd><a href="https://alt.fedoraproject.org/">Alternative Downloads</a></dd>
</dl>
</div>
</div>
<div class="col-sm-3 col-xs-6 widget">
<h3 class="widget-title">Support</h3>
<div class="widget-body">
<dl>
<dd><a href="https://fedoraproject.org/wiki/Communicating_and_getting_help">Get Help</a></dd>
<dd><a href="https://ask.fedoraproject.org/">Ask Fedora</a></dd>
<dd><a href="https://fedoraproject.org/wiki/Common_F27_bugs">Common Bugs</a></dd>
<dd><a href="https://developer.fedoraproject.org/">Fedora Developer Portal</a></dd>
<dd><a href="https://docs.fedoraproject.org/f27/install-guide/index.html">Installation Guide</a></dd>
</dl>
</div>
</div>
<div class="col-sm-3 col-xs-6 widget">
<h3 class="widget-title">Join</h3>
<div class="widget-body">
<dl>
<dd><a href="https://fedoraproject.org/wiki/Join">Join Fedora</a></dd>
<dd><a href="http://fedoraplanet.org">Planet Fedora</a></dd>
<dd><a href="https://fedoraproject.org/wiki/SIGs">Fedora SIGs</a></dd>
<dd><a href="https://admin.fedoraproject.org/accounts/">Fedora Account System</a></dd>
<dd><a href="https://fedoracommunity.org/">Fedora Community</a></dd>
</dl>
</div>
</div>
</div> <!-- /row of widgets -->
<div class="row">
<div class="col-md-2">
<div class="widget-body">
<a href="https://www.redhat.com/"><img class="rh-logo" src="../../../master/_images/redhat-logo.png" alt="Red Hat Logo" /></a>
</div>
</div>
<div class="col-md-7">
<div class="widget-body">
<p class="sponsor">Fedora is sponsored by Red Hat.</p>
<p class="sponsor"><a href="https://www.redhat.com/en/technologies/linux-platforms/articles/relationship-between-fedora-and-rhel">Learn more about the relationship between Red Hat and Fedora &raquo;</a></p>
<p class="copy">&copy; 2017 Red Hat, Inc. and others. Please send any comments or corrections to the <a href="https://pagure.io/fedora-docs/docs-fp-o">documentation team</a></p>
</div>
</div>
</div> <!-- /row of widgets -->
</div>
</div>
</div>
<!-- jQuery (necessary for Bootstrap's JavaScript plugins) -->
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>
<!-- Latest compiled and minified JavaScript -->
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/js/bootstrap.min.js"></script>
<script src="../../../master/_javascripts/bootstrap-offcanvas.js" type="text/javascript"></script>
<script type="text/javascript">
/*<![CDATA[*/
$(document).ready(function() {
$("[id^='topicGroup']").on('show.bs.collapse', function (event) {
if (!($(event.target).attr('id').match(/^topicSubGroup/))) {
$(this).parent().find("[id^='tgSpan']").toggleClass("fa-angle-right fa-angle-down");
}
});
$("[id^='topicGroup']").on('hide.bs.collapse', function (event) {
if (!($(event.target).attr('id').match(/^topicSubGroup/))) {
$(this).parent().find("[id^='tgSpan']").toggleClass("fa-angle-right fa-angle-down");
}
});
$("[id^='topicSubGroup']").on('show.bs.collapse', function () {
$(this).parent().find("[id^='sgSpan']").toggleClass("fa-caret-right fa-caret-down");
});
$("[id^='topicSubGroup']").on('hide.bs.collapse', function () {
$(this).parent().find("[id^='sgSpan']").toggleClass("fa-caret-right fa-caret-down");
});
});
/*]]>*/
</script>
</body>
</html>

View file

@ -1,702 +0,0 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta content="IE=edge" http-equiv="X-UA-Compatible">
<meta content="width=device-width, initial-scale=1.0" name="viewport">
<title>Defensive Coding Guide | Defensive Coding Guide | Specific Programming Tasks | Processes</title>
<!-- Bootstrap -->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css">
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap-theme.min.css">
<!-- Overpass Font -->
<link rel="stylesheet" href="https://overpass-30e2.kxcdn.com/overpass.css">
<link href="../../../master/_stylesheets/asciibinder.css" rel="stylesheet" />
<!-- HTML5 shim and Respond.js for IE8 support of HTML5 elements and media queries -->
<!-- WARNING: Respond.js doesn't work if you view the page via file:// -->
<!--[if lt IE 9]>
<script src="https://oss.maxcdn.com/html5shiv/3.7.2/html5shiv.min.js"></script>
<script src="https://oss.maxcdn.com/respond/1.4.2/respond.min.js"></script>
<![endif]-->
<link href="../../../master/_images/favicon32x32.png" rel="shortcut icon" type="text/css">
<!--[if IE]><link rel="shortcut icon" href="../../../master/_images/favicon.ico"><![endif]-->
<meta content="AsciiBinder" name="application-name">
</head>
<body>
<div class="navbar navbar-default" role="navigation">
<div class="container-fluid">
<div class="navbar-header">
<a class="navbar-brand" href="https://docs.fedoraproject.org/"><img alt="Fedora Documentation" src="../../../master/_images/fedora.svg"></a>
</div>
</div>
</div>
<div class="container">
<p class="toggle-nav visible-xs pull-left">
<button class="btn btn-default btn-sm" type="button" data-toggle="offcanvas">Toggle nav</button>
</p>
<ol class="breadcrumb">
<li class="sitename">
<a href="../../../index.html">Home</a>
</li>
<li class="hidden-xs active">
<a href="../../en-US/index.html">Defensive Coding Guide </a>
</li>
<li class="hidden-xs active">
<a href="../../en-US/index.html">Defensive Coding Guide</a>
</li>
<li class="hidden-xs active"><a href="../../en-US/tasks/Tasks-Library_Design.html">Specific Programming Tasks</a></li>
<li class="hidden-xs active">
Processes
</li>
</ol>
<div class="row row-offcanvas row-offcanvas-left">
<div class="col-xs-8 col-sm-3 col-md-3 sidebar sidebar-offcanvas">
<ul class="nav nav-sidebar">
<li class="nav-header">
<a class="" href="#" data-toggle="collapse" data-target="#topicGroup0">
<span id="tgSpan0" class="fa fa-angle-down"></span>Defensive Coding Guide
</a>
<ul id="topicGroup0" class="collapse in list-unstyled">
<li><a class="" href="../../en-US/index.html">Book Information</a></li>
<li class="nav-header">
<a class="" href="#" data-toggle="collapse" data-target="#topicSubGroup-0-1">
<span id="sgSpan-0-1" class="fa fa-caret-right"></span>&nbsp;Programming Languages
</a>
<ul id="topicSubGroup-0-1" class="nav-tertiary list-unstyled collapse">
<li><a class="" href="../../en-US/programming-languages/C.html">The C Programming Language</a></li>
<li><a class="" href="../../en-US/programming-languages/CXX.html">The C++ Programming&nbsp;Language</a></li>
<li><a class="" href="../../en-US/programming-languages/Java.html">The Java Programming Language</a></li>
<li><a class="" href="../../en-US/programming-languages/Python.html">The Python Programming Language</a></li>
<li><a class="" href="../../en-US/programming-languages/Shell.html">Shell Programming and bash</a></li>
<li><a class="" href="../../en-US/programming-languages/Go.html">The Go Programming Language</a></li>
<li><a class="" href="../../en-US/programming-languages/Vala.html">The Vala Programming Language</a></li>
</ul>
</li>
<li class="nav-header">
<a class="" href="#" data-toggle="collapse" data-target="#topicSubGroup-0-2">
<span id="sgSpan-0-2" class="fa fa-caret-down"></span>&nbsp;Specific Programming Tasks
</a>
<ul id="topicSubGroup-0-2" class="nav-tertiary list-unstyled collapse in">
<li><a class="" href="../../en-US/tasks/Tasks-Library_Design.html">Library Design</a></li>
<li><a class="" href="../../en-US/tasks/Tasks-Descriptors.html">File Descriptor Management</a></li>
<li><a class="" href="../../en-US/tasks/Tasks-File_System.html">File System Manipulation</a></li>
<li><a class="" href="../../en-US/tasks/Tasks-Temporary_Files.html">Temporary Files</a></li>
<li><a class=" active" href="../../en-US/tasks/Tasks-Processes.html">Processes</a></li>
<li><a class="" href="../../en-US/tasks/Tasks-Serialization.html">Serialization and Deserialization</a></li>
<li><a class="" href="../../en-US/tasks/Tasks-Cryptography.html">Cryptography</a></li>
<li><a class="" href="../../en-US/tasks/Tasks-Packaging.html">RPM Packaging</a></li>
</ul>
</li>
<li class="nav-header">
<a class="" href="#" data-toggle="collapse" data-target="#topicSubGroup-0-3">
<span id="sgSpan-0-3" class="fa fa-caret-right"></span>&nbsp;Implementing Security Features
</a>
<ul id="topicSubGroup-0-3" class="nav-tertiary list-unstyled collapse">
<li><a class="" href="../../en-US/features/Features-Authentication.html">Authentication and Authorization</a></li>
<li><a class="" href="../../en-US/features/Features-TLS.html">Transport Layer Security (TLS)</a></li>
<li><a class="" href="../../en-US/features/Features-HSM.html">Hardware Security Modules and Smart Cards</a></li>
</ul>
</li>
<li><a class="" href="../../en-US/Revision_History.html">Revision History</a></li>
</ul>
</li>
</ul>
</div>
<div class="col-xs-12 col-sm-9 col-md-9 main">
<div class="page-header">
<h2>Processes</h2>
</div>
<div class="sect1">
<h2 id="sect-Defensive_Coding-Tasks-Processes-Creation"><a class="anchor" href="#sect-Defensive_Coding-Tasks-Processes-Creation"></a>Creating Safe Processes</h2>
<div class="sectionbody">
<div class="paragraph">
<p>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 <a href="#sect-Defensive_Coding-Tasks-Descriptors-Child_Processes">[sect-Defensive_Coding-Tasks-Descriptors-Child_Processes]</a>.</p>
</div>
<div class="sect2">
<h3 id="obtaining-the-program-path-and-the-command-line-template"><a class="anchor" href="#obtaining-the-program-path-and-the-command-line-template"></a>Obtaining the Program Path and the Command-line Template</h3>
<div class="paragraph">
<p>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.</p>
</div>
<div class="paragraph">
<p>The configured program name should be an absolute path. If it
is a relative path, the contents of the <code>PATH</code>
must be obtained in a secure manner (see <a href="#sect-Defensive_Coding-Tasks-secure_getenv">Accessing Environment Variables</a>).
If the <code>PATH</code> variable is not set or untrusted,
the safe default <code>/bin:/usr/bin</code> must be
used.</p>
</div>
<div class="paragraph">
<p>If too much flexibility is provided here, it may allow
invocation of arbitrary programs without proper authorization.</p>
</div>
</div>
<div class="sect2">
<h3 id="sect-Defensive_Coding-Tasks-Processes-execve"><a class="anchor" href="#sect-Defensive_Coding-Tasks-Processes-execve"></a>Bypassing the Shell</h3>
<div class="paragraph">
<p>Child processes should be created without involving the system
shell.</p>
</div>
<div class="paragraph">
<p>For C/C++, <code>system</code> should not be used.
The <code>posix_spawn</code> function can be used
instead, or a combination <code>fork</code> and
<code>execve</code>. (In some cases, it may be
preferable to use <code>vfork</code> or the
Linux-specific <code>clone</code> system call instead
of <code>fork</code>.)</p>
</div>
<div class="paragraph">
<p>In Python, the <code>subprocess</code> module bypasses
the shell by default (when the <code>shell</code>
keyword argument is not set to true).
<code>os.system</code> should not be used.</p>
</div>
<div class="paragraph">
<p>The Java class <code>java.lang.ProcessBuilder</code> can be
used to create subprocesses without interference from the
system shell.</p>
</div>
<div class="admonitionblock important">
<table>
<tr>
<td class="icon">
<i class="fa icon-important" title="Important"></i>
</td>
<td class="content">
<div class="title">Portability notice</div>
<div class="paragraph">
<p>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.</p>
</div>
</td>
</tr>
</table>
</div>
<div class="paragraph">
<p>Note that some common applications (notably
<strong class="application">ssh</strong>) 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.</p>
</div>
</div>
<div class="sect2">
<h3 id="sect-Defensive_Coding-Tasks-Processes-environ"><a class="anchor" href="#sect-Defensive_Coding-Tasks-Processes-environ"></a>Specifying the Process Environment</h3>
<div class="paragraph">
<p>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.</p>
</div>
<div class="paragraph">
<p>In C/C++, the environment should be constructed as an array of
strings and passed as the <code>envp</code> argument to
<code>posix_spawn</code> or <code>execve</code>.
The functions <code>setenv</code>,
<code>unsetenv</code> and <code>putenv</code>
should not be used. They are not thread-safe and suffer from
memory leaks.</p>
</div>
<div class="paragraph">
<p>Python programs need to specify a <code>dict</code> for
the the <code>env</code> argument of the
<code>subprocess.Popen</code> constructor.
The Java class <code>java.lang.ProcessBuilder</code>
provides a <code>environment()</code> method,
which returns a map that can be manipulated.</p>
</div>
<div class="paragraph">
<p>The following list provides guidelines for selecting the set
of environment variables passed to the child process.</p>
</div>
<div class="ulist">
<ul>
<li>
<p><code>PATH</code> should be initialized to
<code>/bin:/usr/bin</code>.</p>
</li>
<li>
<p><code>USER</code> and <code>HOME</code> can be inhereted
from the parent process environment, or they can be
initialized from the <code>pwent</code> structure
for the user.</p>
</li>
<li>
<p>The <code>DISPLAY</code> and <code>XAUTHORITY</code>
variables should be passed to the subprocess if it is an X
program. Note that this will typically not work across trust
boundaries because <code>XAUTHORITY</code> refers to a file
with <code>0600</code> permissions.</p>
</li>
<li>
<p>The location-related environment variables
<code>LANG</code>, <code>LANGUAGE</code>,
<code>LC_ADDRESS</code>, <code>LC_ALL</code>,
<code>LC_COLLATE</code>, <code>LC_CTYPE</code>,
<code>LC_IDENTIFICATION</code>,
<code>LC_MEASUREMENT</code>, <code>LC_MESSAGES</code>,
<code>LC_MONETARY</code>, <code>LC_NAME</code>,
<code>LC_NUMERIC</code>, <code>LC_PAPER</code>,
<code>LC_TELEPHONE</code> and <code>LC_TIME</code>
can be passed to the subprocess if present.</p>
</li>
<li>
<p>The called process may need application-specific
environment variables, for example for passing passwords.
(See <a href="#sect-Defensive_Coding-Tasks-Processes-Command_Line_Visibility">Passing Secrets to Subprocesses</a>.)</p>
</li>
<li>
<p>All other environment variables should be dropped. Names
for new environment variables should not be accepted from
untrusted sources.</p>
</li>
</ul>
</div>
</div>
<div class="sect2">
<h3 id="robust-argument-list-processing"><a class="anchor" href="#robust-argument-list-processing"></a>Robust Argument List Processing</h3>
<div class="paragraph">
<p>When invoking a program, it is sometimes necessary to include
data from untrusted sources. Such data should be checked
against embedded <code>NUL</code> characters because the
system APIs will silently truncate argument strings at the first
<code>NUL</code> character.</p>
</div>
<div class="paragraph">
<p>The following recommendations assume that the program being
invoked uses GNU-style option processing using
<code>getopt_long</code>. This convention is widely
used, but it is just that, and individual programs might
interpret a command line in a different way.</p>
</div>
<div class="paragraph">
<p>If the untrusted data has to go into an option, use the
<code>--option-name=VALUE</code> syntax, placing the
option and its value into the same command line argument.
This avoids any potential confusion if the data starts with
<code>-</code>.</p>
</div>
<div class="paragraph">
<p>For positional arguments, terminate the option list with a
single <code class="option">--</code> marker after the last option, and
include the data at the right position. The
<code class="option">--</code> marker terminates option processing, and
the data will not be treated as an option even if it starts
with a dash.</p>
</div>
</div>
<div class="sect2">
<h3 id="sect-Defensive_Coding-Tasks-Processes-Command_Line_Visibility"><a class="anchor" href="#sect-Defensive_Coding-Tasks-Processes-Command_Line_Visibility"></a>Passing Secrets to Subprocesses</h3>
<div class="paragraph">
<p>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 <a href="#sect-Defensive_Coding-Tasks-Processes-environ">Specifying the Process Environment</a>.)</p>
</div>
<div class="admonitionblock important">
<table>
<tr>
<td class="icon">
<i class="fa icon-important" title="Important"></i>
</td>
<td class="content">
<div class="title">Portability notice</div>
<div class="paragraph">
<p>On some UNIX-like systems (notably Solaris), environment
variables can be read by any system user, just like command
lines.</p>
</div>
</td>
</tr>
</table>
</div>
<div class="paragraph">
<p>If the environment-based approach cannot be used due to
portability concerns, the data can be passed on standard
input. Some programs (notably <strong class="application">gpg</strong>)
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.</p>
</div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="handling-child-process-termination"><a class="anchor" href="#handling-child-process-termination"></a>Handling Child Process Termination</h2>
<div class="sectionbody">
<div class="paragraph">
<p>When child processes terminate, the parent process is signalled.
A stub of the terminated processes (a
<strong>zombie</strong>, shown as
<code>&lt;defunct&gt;</code> by
<strong class="application">ps</strong>) is kept around until the status
information is collected (<strong>reaped</strong>) by the
parent process. Over the years, several interfaces for this
have been invented:</p>
</div>
<div class="ulist">
<ul>
<li>
<p>The parent process calls <code>wait</code>,
<code>waitpid</code>, <code>waitid</code>,
<code>wait3</code> or <code>wait4</code>,
without specifying a process ID. This will deliver any
matching process ID. This approach is typically used from
within event loops.</p>
</li>
<li>
<p>The parent process calls <code>waitpid</code>,
<code>waitid</code>, or <code>wait4</code>,
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.</p>
</li>
<li>
<p>The parent process installs a handler for the
<code>SIGCHLD</code> signal, using
<code>sigaction</code>, and specifies to the
<code>SA_NOCLDWAIT</code> flag.
This approach could be used by event loops as well.</p>
</li>
</ul>
</div>
<div class="paragraph">
<p>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).</p>
</div>
<div class="paragraph">
<p>At the moment, the parent process should explicitly wait for
termination of the child process using
<code>waitpid</code> or <code>waitid</code>,
and hope that the status is not collected by an event loop
first.</p>
</div>
</div>
</div>
<div class="sect1">
<h2 id="code-suid-code-code-sgid-code-processes"><a class="anchor" href="#code-suid-code-code-sgid-code-processes"></a><code>SUID</code>/<code>SGID</code> processes</h2>
<div class="sectionbody">
<div class="paragraph">
<p>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 <code>SUID</code> 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
<code>SGID</code> bit, the effective group ID is set to
the group of the executable file.</p>
</div>
<div class="paragraph">
<p>Linux supports <strong>fscaps</strong>, which can grant
additional capabilities to a process in a finer-grained manner.
Additional mechanisms can be provided by loadable security
modules.</p>
</div>
<div class="paragraph">
<p>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.</p>
</div>
<div class="sect2">
<h3 id="sect-Defensive_Coding-Tasks-secure_getenv"><a class="anchor" href="#sect-Defensive_Coding-Tasks-secure_getenv"></a>Accessing Environment Variables</h3>
<div class="paragraph">
<p>The following steps are required so that a program does not
accidentally pick up untrusted data from environment
variables.</p>
</div>
<div class="ulist">
<ul>
<li>
<p>Compile your C/C++ sources with <code>-D_GNU_SOURCE</code>.
The Autoconf macro <code>AC_GNU_SOURCE</code> ensures this.</p>
</li>
<li>
<p>Check for the presence of the <code>secure_getenv</code>
and <code><em>secure_getenv</code> function. The Autoconf
directive <code>AC_CHECK_FUNCS([</em>secure_getenv secure_getenv])</code>
performs these checks.</p>
</li>
<li>
<p>Arrange for a proper definition of the
<code>secure_getenv</code> function. See <a href="#ex-Defensive_Coding-Tasks-secure_getenv">Obtaining a definition for <code>secure_getenv</code></a>.</p>
</li>
<li>
<p>Use <code>secure_getenv</code> instead of
<code>getenv</code> to obtain the value of critical
environment variables. <code>secure_getenv</code>
will pretend the variable has not bee set if the process
environment is not trusted.</p>
</li>
</ul>
</div>
<div class="paragraph">
<p>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.</p>
</div>
<div class="paragraph">
<p>Either the <code>secure_getenv</code> function or the
<code>__secure_getenv</code> is available from GNU libc.</p>
</div>
<div id="ex-Defensive_Coding-Tasks-secure_getenv" class="exampleblock">
<div class="title">Example 1. Obtaining a definition for <code>secure_getenv</code></div>
<div class="content">
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code data-lang="c"><span style="color:#579">#include</span> <span style="color:#B44;font-weight:bold">&lt;stdlib.h&gt;</span>
<span style="color:#579">#ifndef</span> HAVE_SECURE_GETENV
<span style="color:#579"># ifdef</span> HAVE__SECURE_GETENV
<span style="color:#579"># define</span> secure_getenv __secure_getenv
<span style="color:#579"># else</span>
<span style="color:#579"># error</span> neither secure_getenv nor __secure_getenv are available
<span style="color:#579"># endif</span>
<span style="color:#579">#endif</span></code></pre>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="sect-Defensive_Coding-Tasks-Processes-Daemons"><a class="anchor" href="#sect-Defensive_Coding-Tasks-Processes-Daemons"></a>Daemons</h2>
<div class="sectionbody">
<div class="paragraph">
<p>Background processes providing system services
(<strong>daemons</strong>) need to decouple themselves from
the controlling terminal and the parent process environment:</p>
</div>
<div class="ulist">
<ul>
<li>
<p>Fork.</p>
</li>
<li>
<p>In the child process, call <code>setsid</code>. The
parent process can simply exit (using
<code>_exit</code>, to avoid running clean-up
actions twice).</p>
</li>
<li>
<p>In the child process, fork again. Processing continues in
the child process. Again, the parent process should just
exit.</p>
</li>
<li>
<p>Replace the descriptors 0, 1, 2 with a descriptor for
<code>/dev/null</code>. Logging should be
redirected to <strong class="application">syslog</strong>.</p>
</li>
</ul>
</div>
<div class="paragraph">
<p>Older instructions for creating daemon processes recommended a
call to <code>umask(0)</code>. 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 <strong>umask</strong> needs setting, a restrictive
value such as <code>027</code> or <code>077</code>
is recommended.</p>
</div>
<div class="paragraph">
<p>Other aspects of the process environment may have to changed as
well (environment variables, signal handler disposition).</p>
</div>
<div class="paragraph">
<p>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
<strong class="application">systemd</strong>). 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.</p>
</div>
</div>
</div>
<div class="sect1">
<h2 id="semantics-of-command-line-arguments"><a class="anchor" href="#semantics-of-command-line-arguments"></a>Semantics of Command-line Arguments</h2>
<div class="sectionbody">
<div class="paragraph">
<p>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,
<strong class="application">python</strong> with the
<code class="option">-c</code> option).</p>
</div>
<div class="paragraph">
<p>Similar concerns apply to environment variables, the contents
of the current directory and its subdirectories.</p>
</div>
<div class="paragraph">
<p>Consequently, careful analysis is required if it is safe to
pass untrusted data to another program.</p>
</div>
</div>
</div>
<div class="sect1">
<h2 id="sect-Defensive_Coding-Tasks-Processes-Fork-Parallel"><a class="anchor" href="#sect-Defensive_Coding-Tasks-Processes-Fork-Parallel"></a><code>fork</code> as a Primitive for Parallelism</h2>
<div class="sectionbody">
<div class="paragraph">
<p>A call to <code>fork</code> which is not immediately
followed by a call to <code>execve</code> (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 <code>fork</code>
should be replaced with proper child processes or threads.</p>
</div>
</div>
</div>
</div>
</div>
</div>
<div id="bottom" class="text-muted py-3" >
<div class="foot">
<div class="container">
<div class="row footerlinks">
<div class="col-sm-3 col-xs-6 widget">
<h3 class="widget-title">About</h3>
<div class="widget-body">
<dl>
<dd><a href="https://fedoraproject.org/wiki/Overview">About Fedora</a></dd>
<dd><a href="https://getfedora.org/en/sponsors">Sponsors</a></dd>
<dd><a href="https://fedoramagazine.org">Fedora Magazine</a></dd>
<dd><a href="https://fedoraproject.org/wiki/Legal:Main#Legal">Legal</a></dd>
</dl>
<ul class="list-inline">
<li>
<a href="https://www.facebook.com/TheFedoraProject" class="btn-social btn-outline"><i class="fa fa-fw fa-facebook"></i></a>
</li>
<li>
<a href="https://plus.google.com/112917221531140868607" class="btn-social btn-outline"><i class="fa fa-fw fa-google-plus"></i></a>
</li>
<li>
<a href="https://twitter.com/fedora" class="btn-social btn-outline"><i class="fa fa-fw fa-twitter"></i></a>
</li>
</ul>
</div>
</div>
<div class="col-sm-3 col-xs-6 widget">
<h3 class="widget-title uppercase">Download</h3>
<div class="widget-body">
<dl>
<dd><a href="https://getfedora.org/en/workstation/download">Get Fedora Workstation</a></dd>
<dd><a href="https://getfedora.org/en/server/download">Get Fedora Server</a></dd>
<dd><a href="https://getfedora.org/en/atomic/download">Get Fedora Atomic</a></dd>
<dd><a href="https://spins.fedoraproject.org">Fedora Spins</a></dd>
<dd><a href="https://labs.fedoraproject.org">Fedora Labs</a></dd>
<dd><a href="https://arm.fedoraproject.org">Fedora ARM<span class="sup">&reg;</span></a></dd>
<dd><a href="https://alt.fedoraproject.org/">Alternative Downloads</a></dd>
</dl>
</div>
</div>
<div class="col-sm-3 col-xs-6 widget">
<h3 class="widget-title">Support</h3>
<div class="widget-body">
<dl>
<dd><a href="https://fedoraproject.org/wiki/Communicating_and_getting_help">Get Help</a></dd>
<dd><a href="https://ask.fedoraproject.org/">Ask Fedora</a></dd>
<dd><a href="https://fedoraproject.org/wiki/Common_F27_bugs">Common Bugs</a></dd>
<dd><a href="https://developer.fedoraproject.org/">Fedora Developer Portal</a></dd>
<dd><a href="https://docs.fedoraproject.org/f27/install-guide/index.html">Installation Guide</a></dd>
</dl>
</div>
</div>
<div class="col-sm-3 col-xs-6 widget">
<h3 class="widget-title">Join</h3>
<div class="widget-body">
<dl>
<dd><a href="https://fedoraproject.org/wiki/Join">Join Fedora</a></dd>
<dd><a href="http://fedoraplanet.org">Planet Fedora</a></dd>
<dd><a href="https://fedoraproject.org/wiki/SIGs">Fedora SIGs</a></dd>
<dd><a href="https://admin.fedoraproject.org/accounts/">Fedora Account System</a></dd>
<dd><a href="https://fedoracommunity.org/">Fedora Community</a></dd>
</dl>
</div>
</div>
</div> <!-- /row of widgets -->
<div class="row">
<div class="col-md-2">
<div class="widget-body">
<a href="https://www.redhat.com/"><img class="rh-logo" src="../../../master/_images/redhat-logo.png" alt="Red Hat Logo" /></a>
</div>
</div>
<div class="col-md-7">
<div class="widget-body">
<p class="sponsor">Fedora is sponsored by Red Hat.</p>
<p class="sponsor"><a href="https://www.redhat.com/en/technologies/linux-platforms/articles/relationship-between-fedora-and-rhel">Learn more about the relationship between Red Hat and Fedora &raquo;</a></p>
<p class="copy">&copy; 2017 Red Hat, Inc. and others. Please send any comments or corrections to the <a href="https://pagure.io/fedora-docs/docs-fp-o">documentation team</a></p>
</div>
</div>
</div> <!-- /row of widgets -->
</div>
</div>
</div>
<!-- jQuery (necessary for Bootstrap's JavaScript plugins) -->
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>
<!-- Latest compiled and minified JavaScript -->
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/js/bootstrap.min.js"></script>
<script src="../../../master/_javascripts/bootstrap-offcanvas.js" type="text/javascript"></script>
<script type="text/javascript">
/*<![CDATA[*/
$(document).ready(function() {
$("[id^='topicGroup']").on('show.bs.collapse', function (event) {
if (!($(event.target).attr('id').match(/^topicSubGroup/))) {
$(this).parent().find("[id^='tgSpan']").toggleClass("fa-angle-right fa-angle-down");
}
});
$("[id^='topicGroup']").on('hide.bs.collapse', function (event) {
if (!($(event.target).attr('id').match(/^topicSubGroup/))) {
$(this).parent().find("[id^='tgSpan']").toggleClass("fa-angle-right fa-angle-down");
}
});
$("[id^='topicSubGroup']").on('show.bs.collapse', function () {
$(this).parent().find("[id^='sgSpan']").toggleClass("fa-caret-right fa-caret-down");
});
$("[id^='topicSubGroup']").on('hide.bs.collapse', function () {
$(this).parent().find("[id^='sgSpan']").toggleClass("fa-caret-right fa-caret-down");
});
});
/*]]>*/
</script>
</body>
</html>

File diff suppressed because it is too large Load diff

View file

@ -1,472 +0,0 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta content="IE=edge" http-equiv="X-UA-Compatible">
<meta content="width=device-width, initial-scale=1.0" name="viewport">
<title>Defensive Coding Guide | Defensive Coding Guide | Specific Programming Tasks | Temporary Files</title>
<!-- Bootstrap -->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css">
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap-theme.min.css">
<!-- Overpass Font -->
<link rel="stylesheet" href="https://overpass-30e2.kxcdn.com/overpass.css">
<link href="../../../master/_stylesheets/asciibinder.css" rel="stylesheet" />
<!-- HTML5 shim and Respond.js for IE8 support of HTML5 elements and media queries -->
<!-- WARNING: Respond.js doesn't work if you view the page via file:// -->
<!--[if lt IE 9]>
<script src="https://oss.maxcdn.com/html5shiv/3.7.2/html5shiv.min.js"></script>
<script src="https://oss.maxcdn.com/respond/1.4.2/respond.min.js"></script>
<![endif]-->
<link href="../../../master/_images/favicon32x32.png" rel="shortcut icon" type="text/css">
<!--[if IE]><link rel="shortcut icon" href="../../../master/_images/favicon.ico"><![endif]-->
<meta content="AsciiBinder" name="application-name">
</head>
<body>
<div class="navbar navbar-default" role="navigation">
<div class="container-fluid">
<div class="navbar-header">
<a class="navbar-brand" href="https://docs.fedoraproject.org/"><img alt="Fedora Documentation" src="../../../master/_images/fedora.svg"></a>
</div>
</div>
</div>
<div class="container">
<p class="toggle-nav visible-xs pull-left">
<button class="btn btn-default btn-sm" type="button" data-toggle="offcanvas">Toggle nav</button>
</p>
<ol class="breadcrumb">
<li class="sitename">
<a href="../../../index.html">Home</a>
</li>
<li class="hidden-xs active">
<a href="../../en-US/index.html">Defensive Coding Guide </a>
</li>
<li class="hidden-xs active">
<a href="../../en-US/index.html">Defensive Coding Guide</a>
</li>
<li class="hidden-xs active"><a href="../../en-US/tasks/Tasks-Library_Design.html">Specific Programming Tasks</a></li>
<li class="hidden-xs active">
Temporary Files
</li>
</ol>
<div class="row row-offcanvas row-offcanvas-left">
<div class="col-xs-8 col-sm-3 col-md-3 sidebar sidebar-offcanvas">
<ul class="nav nav-sidebar">
<li class="nav-header">
<a class="" href="#" data-toggle="collapse" data-target="#topicGroup0">
<span id="tgSpan0" class="fa fa-angle-down"></span>Defensive Coding Guide
</a>
<ul id="topicGroup0" class="collapse in list-unstyled">
<li><a class="" href="../../en-US/index.html">Book Information</a></li>
<li class="nav-header">
<a class="" href="#" data-toggle="collapse" data-target="#topicSubGroup-0-1">
<span id="sgSpan-0-1" class="fa fa-caret-right"></span>&nbsp;Programming Languages
</a>
<ul id="topicSubGroup-0-1" class="nav-tertiary list-unstyled collapse">
<li><a class="" href="../../en-US/programming-languages/C.html">The C Programming Language</a></li>
<li><a class="" href="../../en-US/programming-languages/CXX.html">The C++ Programming&nbsp;Language</a></li>
<li><a class="" href="../../en-US/programming-languages/Java.html">The Java Programming Language</a></li>
<li><a class="" href="../../en-US/programming-languages/Python.html">The Python Programming Language</a></li>
<li><a class="" href="../../en-US/programming-languages/Shell.html">Shell Programming and bash</a></li>
<li><a class="" href="../../en-US/programming-languages/Go.html">The Go Programming Language</a></li>
<li><a class="" href="../../en-US/programming-languages/Vala.html">The Vala Programming Language</a></li>
</ul>
</li>
<li class="nav-header">
<a class="" href="#" data-toggle="collapse" data-target="#topicSubGroup-0-2">
<span id="sgSpan-0-2" class="fa fa-caret-down"></span>&nbsp;Specific Programming Tasks
</a>
<ul id="topicSubGroup-0-2" class="nav-tertiary list-unstyled collapse in">
<li><a class="" href="../../en-US/tasks/Tasks-Library_Design.html">Library Design</a></li>
<li><a class="" href="../../en-US/tasks/Tasks-Descriptors.html">File Descriptor Management</a></li>
<li><a class="" href="../../en-US/tasks/Tasks-File_System.html">File System Manipulation</a></li>
<li><a class=" active" href="../../en-US/tasks/Tasks-Temporary_Files.html">Temporary Files</a></li>
<li><a class="" href="../../en-US/tasks/Tasks-Processes.html">Processes</a></li>
<li><a class="" href="../../en-US/tasks/Tasks-Serialization.html">Serialization and Deserialization</a></li>
<li><a class="" href="../../en-US/tasks/Tasks-Cryptography.html">Cryptography</a></li>
<li><a class="" href="../../en-US/tasks/Tasks-Packaging.html">RPM Packaging</a></li>
</ul>
</li>
<li class="nav-header">
<a class="" href="#" data-toggle="collapse" data-target="#topicSubGroup-0-3">
<span id="sgSpan-0-3" class="fa fa-caret-right"></span>&nbsp;Implementing Security Features
</a>
<ul id="topicSubGroup-0-3" class="nav-tertiary list-unstyled collapse">
<li><a class="" href="../../en-US/features/Features-Authentication.html">Authentication and Authorization</a></li>
<li><a class="" href="../../en-US/features/Features-TLS.html">Transport Layer Security (TLS)</a></li>
<li><a class="" href="../../en-US/features/Features-HSM.html">Hardware Security Modules and Smart Cards</a></li>
</ul>
</li>
<li><a class="" href="../../en-US/Revision_History.html">Revision History</a></li>
</ul>
</li>
</ul>
</div>
<div class="col-xs-12 col-sm-9 col-md-9 main">
<div class="page-header">
<h2>Temporary Files</h2>
</div>
<div id="preamble">
<div class="sectionbody">
<div class="paragraph">
<p>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, <a href="#chap-Defensive_Coding-Tasks-File_System">[chap-Defensive_Coding-Tasks-File_System]</a>.</p>
</div>
<div class="paragraph">
<p>Secure creation of temporary files has four different aspects.</p>
</div>
<div class="ulist">
<ul>
<li>
<p>The location of the directory for temporary files must be
obtained in a secure manner (that is, untrusted environment
variables must be ignored, see <a href="#sect-Defensive_Coding-Tasks-secure_getenv">[sect-Defensive_Coding-Tasks-secure_getenv]</a>).</p>
</li>
<li>
<p>A new file must be created. Reusing an existing file must be
avoided (the <code>/tmp</code> race
condition). This is tricky because traditionally, system-wide
temporary directories shared by all users are used.</p>
</li>
<li>
<p>The file must be created in a way that makes it impossible for
other users to open it.</p>
</li>
<li>
<p>The descriptor for the temporary file should not leak to
subprocesses.</p>
</li>
</ul>
</div>
<div class="paragraph">
<p>All functions mentioned below will take care of these aspects.</p>
</div>
<div class="paragraph">
<p>Traditionally, temporary files are often used to reduce memory
usage of programs. More and more systems use RAM-based file
systems such as <code>tmpfs</code> 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.</p>
</div>
</div>
</div>
<div class="sect1">
<h2 id="chap-Defensive_Coding-Tasks-Temporary_Files-Location"><a class="anchor" href="#chap-Defensive_Coding-Tasks-Temporary_Files-Location"></a>Obtaining the Location of Temporary Directory</h2>
<div class="sectionbody">
<div class="paragraph">
<p>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:</p>
</div>
<div class="ulist">
<ul>
<li>
<p>Use <code>secure_getenv</code> to obtain the value
of the <code>TMPDIR</code> environment variable. If
it is set, convert the path to a fully-resolved absolute
path, using <code>realpath(path, NULL)</code>. Check
if the new path refers to a directory and is writeable. In
this case, use it as the temporary directory.</p>
</li>
<li>
<p>Fall back to <code>/tmp</code>.</p>
</li>
</ul>
</div>
<div class="paragraph">
<p>In Python, you can use the <code>tempfile.tempdir</code>
variable.</p>
</div>
<div class="paragraph">
<p>Java does not support SUID/SGID programs, so you can use the
<code>java.lang.System.getenv(String)</code> method to
obtain the value of the <code>TMPDIR</code> environment
variable, and follow the two steps described above. (Java&#8217;s
default directory selection does not honor
<code>TMPDIR</code>.)</p>
</div>
</div>
</div>
<div class="sect1">
<h2 id="named-temporary-files"><a class="anchor" href="#named-temporary-files"></a>Named Temporary Files</h2>
<div class="sectionbody">
<div class="paragraph">
<p>The <code>mkostemp</code> function creates a named
temporary file. You should specify the
<code>O_CLOEXEC</code> flag to avoid file descriptor leaks
to subprocesses. (Applications which do not use multiple threads
can also use <code>mkstemp</code>, but libraries should
use <code>mkostemp</code>.) For determining the
directory part of the file name pattern, see <a href="#chap-Defensive_Coding-Tasks-Temporary_Files-Location">Obtaining the Location of Temporary Directory</a>.</p>
</div>
<div class="paragraph">
<p>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 <code>mkostemp</code>
multiple times. Do not create additional file names derived
from the name provided by a previous
<code>mkostemp</code> call. However, it is safe to close
the descriptor returned by <code>mkostemp</code> and
reopen the file using the generated name.</p>
</div>
<div class="paragraph">
<p>The Python class <code>tempfile.NamedTemporaryFile</code>
provides similar functionality, except that the file is deleted
automatically by default. Note that you may have to use the
<code>file</code> attribute to obtain the actual file
object because some programming interfaces cannot deal with
file-like objects. The C function <code>mkostemp</code>
is also available as <code>tempfile.mkstemp</code>.</p>
</div>
<div class="paragraph">
<p>In Java, you can use the
<code>java.io.File.createTempFile(String, String,
File)</code> function, using the temporary file location
determined according to <a href="#chap-Defensive_Coding-Tasks-Temporary_Files-Location">Obtaining the Location of Temporary Directory</a>.
Do not use <code>java.io.File.deleteOnExit()</code> 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.</p>
</div>
</div>
</div>
<div class="sect1">
<h2 id="temporary-files-without-names"><a class="anchor" href="#temporary-files-without-names"></a>Temporary Files without Names</h2>
<div class="sectionbody">
<div class="paragraph">
<p>The <code>tmpfile</code> 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.</p>
</div>
<div class="paragraph">
<p>Alternatively, if the maximum size of the temporary file is
known beforehand, the <code>fmemopen</code> function can
be used to create a <code>FILE *</code> object which is
backed by memory.</p>
</div>
<div class="paragraph">
<p>In Python, unnamed temporary files are provided by the
<code>tempfile.TemporaryFile</code> class, and the
<code>tempfile.SpooledTemporaryFile</code> class provides
a way to avoid creation of small temporary files.</p>
</div>
<div class="paragraph">
<p>Java does not support unnamed temporary files.</p>
</div>
</div>
</div>
<div class="sect1">
<h2 id="chap-Defensive_Coding-Tasks-Temporary_Directory"><a class="anchor" href="#chap-Defensive_Coding-Tasks-Temporary_Directory"></a>Temporary Directories</h2>
<div class="sectionbody">
<div class="paragraph">
<p>The <code>mkdtemp</code> function can be used to create
a temporary directory. (For determining the directory part of
the file name pattern, see <a href="#chap-Defensive_Coding-Tasks-Temporary_Files-Location">Obtaining the Location of Temporary Directory</a>.)
The directory is not automatically removed. In Python, this
function is available as <code>tempfile.mkdtemp</code>.
In Java 7, temporary directories can be created using the
<code>java.nio.file.Files.createTempDirectory(Path, String,
FileAttribute&#8230;&#8203;)</code> function.</p>
</div>
<div class="paragraph">
<p>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
<strong>directory traversal</strong>).</p>
</div>
<div class="paragraph">
<p>Removing a directory tree in a completely safe manner is
complicated. Unless there are overriding performance concerns,
the <strong class="application">rm</strong> program should be used, with
the <code class="option">-rf</code> and <code class="option">--</code> options.</p>
</div>
</div>
</div>
<div class="sect1">
<h2 id="compensating-for-unsafe-file-creation"><a class="anchor" href="#compensating-for-unsafe-file-creation"></a>Compensating for Unsafe File Creation</h2>
<div class="sectionbody">
<div class="paragraph">
<p>There are two ways to make a function or program which excepts a
file name safe for use with temporary files. See
<a href="#sect-Defensive_Coding-Tasks-Processes-Creation">[sect-Defensive_Coding-Tasks-Processes-Creation]</a>,
for details on subprocess creation.</p>
</div>
<div class="ulist">
<ul>
<li>
<p>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 <a href="#chap-Defensive_Coding-Tasks-Temporary_Directory">Temporary Directories</a>.)</p>
</li>
<li>
<p>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:</p>
<div class="ulist">
<ul>
<li>
<p>The function or program must not create additional files
whose name is derived from the specified file name or
are otherwise predictable.</p>
</li>
<li>
<p>The function or program must not delete the file before
processing it.</p>
</li>
<li>
<p>It must not access any existing files in the same
directory.</p>
<div class="paragraph">
<p>It is often difficult to check whether these additional
assumptions are matched, therefore this approach is not
recommended.</p>
</div>
</li>
</ul>
</div>
</li>
</ul>
</div>
</div>
</div>
</div>
</div>
</div>
<div id="bottom" class="text-muted py-3" >
<div class="foot">
<div class="container">
<div class="row footerlinks">
<div class="col-sm-3 col-xs-6 widget">
<h3 class="widget-title">About</h3>
<div class="widget-body">
<dl>
<dd><a href="https://fedoraproject.org/wiki/Overview">About Fedora</a></dd>
<dd><a href="https://getfedora.org/en/sponsors">Sponsors</a></dd>
<dd><a href="https://fedoramagazine.org">Fedora Magazine</a></dd>
<dd><a href="https://fedoraproject.org/wiki/Legal:Main#Legal">Legal</a></dd>
</dl>
<ul class="list-inline">
<li>
<a href="https://www.facebook.com/TheFedoraProject" class="btn-social btn-outline"><i class="fa fa-fw fa-facebook"></i></a>
</li>
<li>
<a href="https://plus.google.com/112917221531140868607" class="btn-social btn-outline"><i class="fa fa-fw fa-google-plus"></i></a>
</li>
<li>
<a href="https://twitter.com/fedora" class="btn-social btn-outline"><i class="fa fa-fw fa-twitter"></i></a>
</li>
</ul>
</div>
</div>
<div class="col-sm-3 col-xs-6 widget">
<h3 class="widget-title uppercase">Download</h3>
<div class="widget-body">
<dl>
<dd><a href="https://getfedora.org/en/workstation/download">Get Fedora Workstation</a></dd>
<dd><a href="https://getfedora.org/en/server/download">Get Fedora Server</a></dd>
<dd><a href="https://getfedora.org/en/atomic/download">Get Fedora Atomic</a></dd>
<dd><a href="https://spins.fedoraproject.org">Fedora Spins</a></dd>
<dd><a href="https://labs.fedoraproject.org">Fedora Labs</a></dd>
<dd><a href="https://arm.fedoraproject.org">Fedora ARM<span class="sup">&reg;</span></a></dd>
<dd><a href="https://alt.fedoraproject.org/">Alternative Downloads</a></dd>
</dl>
</div>
</div>
<div class="col-sm-3 col-xs-6 widget">
<h3 class="widget-title">Support</h3>
<div class="widget-body">
<dl>
<dd><a href="https://fedoraproject.org/wiki/Communicating_and_getting_help">Get Help</a></dd>
<dd><a href="https://ask.fedoraproject.org/">Ask Fedora</a></dd>
<dd><a href="https://fedoraproject.org/wiki/Common_F27_bugs">Common Bugs</a></dd>
<dd><a href="https://developer.fedoraproject.org/">Fedora Developer Portal</a></dd>
<dd><a href="https://docs.fedoraproject.org/f27/install-guide/index.html">Installation Guide</a></dd>
</dl>
</div>
</div>
<div class="col-sm-3 col-xs-6 widget">
<h3 class="widget-title">Join</h3>
<div class="widget-body">
<dl>
<dd><a href="https://fedoraproject.org/wiki/Join">Join Fedora</a></dd>
<dd><a href="http://fedoraplanet.org">Planet Fedora</a></dd>
<dd><a href="https://fedoraproject.org/wiki/SIGs">Fedora SIGs</a></dd>
<dd><a href="https://admin.fedoraproject.org/accounts/">Fedora Account System</a></dd>
<dd><a href="https://fedoracommunity.org/">Fedora Community</a></dd>
</dl>
</div>
</div>
</div> <!-- /row of widgets -->
<div class="row">
<div class="col-md-2">
<div class="widget-body">
<a href="https://www.redhat.com/"><img class="rh-logo" src="../../../master/_images/redhat-logo.png" alt="Red Hat Logo" /></a>
</div>
</div>
<div class="col-md-7">
<div class="widget-body">
<p class="sponsor">Fedora is sponsored by Red Hat.</p>
<p class="sponsor"><a href="https://www.redhat.com/en/technologies/linux-platforms/articles/relationship-between-fedora-and-rhel">Learn more about the relationship between Red Hat and Fedora &raquo;</a></p>
<p class="copy">&copy; 2017 Red Hat, Inc. and others. Please send any comments or corrections to the <a href="https://pagure.io/fedora-docs/docs-fp-o">documentation team</a></p>
</div>
</div>
</div> <!-- /row of widgets -->
</div>
</div>
</div>
<!-- jQuery (necessary for Bootstrap's JavaScript plugins) -->
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>
<!-- Latest compiled and minified JavaScript -->
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/js/bootstrap.min.js"></script>
<script src="../../../master/_javascripts/bootstrap-offcanvas.js" type="text/javascript"></script>
<script type="text/javascript">
/*<![CDATA[*/
$(document).ready(function() {
$("[id^='topicGroup']").on('show.bs.collapse', function (event) {
if (!($(event.target).attr('id').match(/^topicSubGroup/))) {
$(this).parent().find("[id^='tgSpan']").toggleClass("fa-angle-right fa-angle-down");
}
});
$("[id^='topicGroup']").on('hide.bs.collapse', function (event) {
if (!($(event.target).attr('id').match(/^topicSubGroup/))) {
$(this).parent().find("[id^='tgSpan']").toggleClass("fa-angle-right fa-angle-down");
}
});
$("[id^='topicSubGroup']").on('show.bs.collapse', function () {
$(this).parent().find("[id^='sgSpan']").toggleClass("fa-caret-right fa-caret-down");
});
$("[id^='topicSubGroup']").on('hide.bs.collapse', function () {
$(this).parent().find("[id^='sgSpan']").toggleClass("fa-caret-right fa-caret-down");
});
});
/*]]>*/
</script>
</body>
</html>

File diff suppressed because one or more lines are too long

View file

@ -1,135 +0,0 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<!-- The above 3 meta tags *must* come first in the head; any other head content must come *after* these tags -->
<title>Fedora Documentation Website</title>
<!-- Bootstrap -->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css">
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap-theme.min.css">
<link rel="stylesheet" href="https://overpass-30e2.kxcdn.com/overpass.css">
<link rel="stylesheet" href="_stylesheets/asciibinder.css">
<!-- HTML5 shim and Respond.js for IE8 support of HTML5 elements and media queries -->
<!-- WARNING: Respond.js doesn't work if you view the page via file:// -->
<!--[if lt IE 9]>
<script src="https://oss.maxcdn.com/html5shiv/3.7.2/html5shiv.min.js"></script>
<script src="https://oss.maxcdn.com/respond/1.4.2/respond.min.js"></script>
<![endif]-->
</head>
<body>
<div class="container">
<div class="row">
<div class="page-header">
<img src="/_images/fedora.svg" class="img-responsive" />
<h2><strong>Fedora Documentation Site</strong></h2>
</div>
</div>
<div class="row">
<div class="col-md-8">
<h4><strong>Fedora Documentation - 404 Page Not Found :(</strong></h4>
<p>Hi! You've arrived at Fedora documentation page which does not actually exist. This may be because you followed a link to an older document which has been retired. For reference, you can find those in our <a href="https://docs-old.fedoraproject.org/">old document archive</a>. Or, you can browse <a href="https://docs.fedoraproject.org/">current docs</a>.</p>
<p>It may also be that this page _should_ exist, but sadly does not. If this is the case, and you know what it should say, you can <a href="https://pagure.io/fedora-docs">contribute via the Docs Project</a>.</p>
</div>
</div>
</div>
</div>
<div id="bottom" class="text-muted py-3" >
<div class="foot">
<div class="container">
<div class="row footerlinks">
<div class="col-sm-3 col-xs-6 widget">
<h3 class="widget-title">About</h3>
<div class="widget-body">
<dl>
<dd><a href="https://fedoraproject.org/wiki/Overview">About Fedora</a></dd>
<dd><a href="https://getfedora.org/en/sponsors">Sponsors</a></dd>
<dd><a href="https://fedoramagazine.org">Fedora Magazine</a></dd>
<dd><a href="https://fedoraproject.org/wiki/Legal:Main#Legal">Legal</a></dd>
</dl>
<ul class="list-inline">
<li>
<a href="https:https://www.facebook.com/TheFedoraProject" class="btn-social btn-outline"><i class="fa fa-fw fa-facebook"></i></a>
</li>
<li>
<a href="https:https://plus.google.com/112917221531140868607" class="btn-social btn-outline"><i class="fa fa-fw fa-google-plus"></i></a>
</li>
<li>
<a href="https:https://twitter.com/fedora" class="btn-social btn-outline"><i class="fa fa-fw fa-twitter"></i></a>
</li>
</ul>
</div>
</div>
<div class="col-sm-3 col-xs-6 widget">
<h3 class="widget-title uppercase">Download</h3>
<div class="widget-body">
<dl>
<dd><a href="https://getfedora.org/en/workstation/download">Get Fedora Workstation</a></dd>
<dd><a href="https://getfedora.org/en/server/download">Get Fedora Server</a></dd>
<dd><a href="https://getfedora.org/en/atomic/download">Get Fedora Atomic</a></dd>
<dd><a href="https://spins.fedoraproject.org">Fedora Spins</a></dd>
<dd><a href="https://labs.fedoraproject.org">Fedora Labs</a></dd>
<dd><a href="https://arm.fedoraproject.org">Fedora ARM<span class="sup">&reg;</span></a></dd>
<dd><a href="https://alt.fedoraproject.org/">Alternative Downloads</a></dd>
</dl>
</div>
</div>
<div class="col-sm-3 col-xs-6 widget">
<h3 class="widget-title">Support</h3>
<div class="widget-body">
<dl>
<dd><a href="https://fedoraproject.org/wiki/Communicating_and_getting_help">Get Help</a></dd>
<dd><a href="https://ask.fedoraproject.org/">Ask Fedora</a></dd>
<dd><a href="https://fedoraproject.org/wiki/Common_F27_bugs">Common Bugs</a></dd>
<dd><a href="https://developer.fedoraproject.org/">Fedora Developer Portal</a></dd>
<dd><a href="https://docs.fedoraproject.org/f27/install-guide/index.html">Installation Guide</a></dd>
</dl>
</div>
</div>
<div class="col-sm-3 col-xs-6 widget">
<h3 class="widget-title">Join</h3>
<div class="widget-body">
<dl>
<dd><a href="https://fedoraproject.org/wiki/Join">Join Fedora</a></dd>
<dd><a href="http://fedoraplanet.org">Planet Fedora</a></dd>
<dd><a href="https://fedoraproject.org/wiki/SIGs">Fedora SIGs</a></dd>
<dd><a href="https://admin.fedoraproject.org/accounts/">Fedora Account System</a></dd>
<dd><a href="https://fedoracommunity.org/">Fedora Community</a></dd>
</dl>
</div>
</div>
</div> <!-- /row of widgets -->
<div class="row">
<div class="col-md-2">
<div class="widget-body">
<a href="https://www.redhat.com/"><img class="rh-logo" src="_images/redhat-logo.png" alt="Red Hat Logo" /></a>
</div>
</div>
<div class="col-md-7">
<div class="widget-body">
<p class="sponsor">Fedora is sponsored by Red Hat.</p>
<p class="sponsor"><a href="https://www.redhat.com/en/technologies/linux-platforms/articles/relationship-between-fedora-and-rhel">Learn more about the relationship between Red Hat and Fedora &raquo;</a></p>
<p class="copy">&copy; 2017 Red Hat, Inc. and others. Please send any comments or corrections to the <a href="https://pagure.io/fedora-docs/docs-fp-o">documentation team</a></p>
</div>
</div>
</div> <!-- /row of widgets -->
</div>
</div>
</div>
<!-- jQuery (necessary for Bootstrap's JavaScript plugins) -->
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>
<!-- Include all compiled plugins (below), or include individual files as needed -->
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/js/bootstrap.min.js"></script>
</body>
</html>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.5 KiB

View file

@ -1,61 +0,0 @@
<?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>

Before

Width:  |  Height:  |  Size: 7.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.9 KiB

View file

@ -1,6 +0,0 @@
$(document).ready(function () {
$('[data-toggle="offcanvas"]').click(function () {
$('.sidebar').show();
$('.row-offcanvas').toggleClass('active');
});
});

View file

@ -1,598 +0,0 @@
@import url(https://maxcdn.bootstrapcdn.com/font-awesome/4.1.0/css/font-awesome.min.css);
/* ------------------------------------------------------------
Image: "Spin" https://www.flickr.com/photos/eflon/3655695161/
Author: eflon https://www.flickr.com/photos/eflon/
License: https://creativecommons.org/licenses/by/2.0/
---------------------------------------------------------------*/
.attribution {
text-align: center;
position: relative;
bottom: -20px;
}
.attribution .btn {
color: #808080;
color: rgba(175,175,175, .65);
font-size: 11px;
}
.attribution .btn:hover {
text-decoration: none;
color: #aaa;
}
.popover-content {
font-size: 12px;
line-height: 1.3;
font-weight: normal;
}
@media screen and (max-width: 980px) {
body {
margin-bottom: 200px;
}
footer {
text-align: center;
}
footer .text-right {
text-align: center !important;
}
#footer_social .first {
margin-left: 0;
}
#footer_social > a {
top: 24px;
}
}
.fa-inverse:hover {
color: #ccc;
}
.collapse a.active {
background-color: #DEEAF4;
color: #000;
position: relative;
}
.collapse a.active:hover {
text-decoration: none;
}
.collapse a.active:before {
background-color: #A0C3E5;
content: "";
display: inline-block;
height: 100%;
left: 0;
position: absolute;
top: 0;
width: 3px;
}
.main h2, .main .h2 {
border-top: 0px;
padding-top: 10px;
font-size: 28px;
}
.page-header {
height: 100% !important;
}
.page-header .img-responsive {
display: inline;
}
.page-header h2 {
font-size: 32px;
display: inline;
vertical-align: bottom;
}
.navbar-brand {
padding: initial;
height: initial;
padding: 12px;
}
.navbar-header h2 {
display: inline;
position: absolute;
font-weight: bold;
margin-top: 50px ;
}
.nav > li > a.hover{
background-color: none;
}
h1, h2, h3, h4, h5, h6, .h1, .h2, .h3, .h4, .h5, .h6 {
position: relative;
}
h2 > a.anchor, h3 > a.anchor, h4 > a.anchor, h5 > a.anchor, h6 > a.anchor {
display: block;
font-weight: normal;
margin-left: -1.5ex;
position: absolute;
text-align: center;
text-decoration: none !important;
visibility: hidden;
width: 1.5ex;
z-index: 1001;
}
h2 > a.anchor:before, h3 > a.anchor:before, h4 > a.anchor:before, h5 > a.anchor:before, h6 > a.anchor:before {
content: "\f0c1";
display: block;
font-family: FontAwesome;
font-size: 0.7em;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
padding-top: 0.2em;
}
h4 > a.anchor:before, h5 > a.anchor:before, h6 > a.anchor:before {
font-size: 1em;
}
h2:hover > a.anchor,
h2 > a.anchor:hover,
h3:hover > a.anchor,
h3 > a.anchor:hover,
h4:hover > a.anchor,
h4 > a.anchor:hover,
h5:hover > a.anchor,
h5 > a.anchor:hover,
h6:hover > a.anchor,
h6 > a.anchor:hover {
visibility: visible;
}
.main {
border-left: 1px solid #e7e7e7;
margin-left: -1px;
padding-left: 25px;
}
@media (min-width: 768px) {
.main {
padding-left: 30px;
}
}
/*
* Sidebar
*/
.nav-header {
font-size: 16px;
}
.nav-header ul {
font-size: 14px;
}
.nav-header ul li a {
display: block;
padding: 5px 20px 5px 25px;
font-size: 13px;
font-weight: normal;
}
.nav-sidebar .fa {
text-align: center;
top: -1px;
width: 14px;
}
.nav-sidebar li a {
color: inherit;
}
.nav-sidebar li a:hover {
color: #000;
}
.nav-sidebar ul li ul.nav-tertiary li a {
padding-left: 50px;
}
.nav-sidebar > li > a {
padding: 7px 0;
}
.nav-sidebar > li > a:focus, .nav-sidebar > li > a:hover {
background: transparent;
}
.sidebar {
font-weight: 300;
display: none;
padding-top: 13px;
}
@media screen and (max-width: 767px) {
.sidebar {
padding-left: 30px;
padding-right: 0;
}
}
@media screen and (min-width: 768px) {
.sidebar {
border-right: 1px solid #e7e7e7;
display: block;
}
}
/*
* Off Canvas
* --------------------------------------------------
*/
body, html {
overflow-x: hidden; /* Prevent scroll on narrow devices */
font-family: "Overpass", sans-serif;
}
.toggle-nav {
margin-right: 20px;
}
@media screen and (max-width: 767px) {
.row-offcanvas {
position: relative;
-webkit-transition: all .25s ease-out;
-o-transition: all .25s ease-out;
transition: all .25s ease-out;
}
.row-offcanvas-right {
right: 0;
}
.row-offcanvas-left {
left: 0;
}
.row-offcanvas-right
.sidebar-offcanvas {
right: -75%; /* 8 columns */
}
.row-offcanvas-left
.sidebar-offcanvas {
left: -75%; /* 8 columns */
}
.row-offcanvas-right.active {
right: 75%; /* 8 columns */
}
.row-offcanvas-left.active {
left: 75%; /* 8 columns */
}
.sidebar-offcanvas {
overflow: hidden;
position: absolute;
top: 0;
width: 75%; /* 8 columns */
}
}
p {
margin: 0 0 1.6em;
}
/* Remnants of Asciidoctor default stylesheet - remove styles as needed */
#map_canvas img, #map_canvas embed, #map_canvas object, .map_canvas img, .map_canvas embed, .map_canvas object { max-width: none !important; }
.left { float: left !important; }
.right { float: right !important; }
.text-left { text-align: left !important; }
.text-right { text-align: right !important; }
.text-center { text-align: center !important; }
.text-justify { text-align: justify !important; }
.hide { display: none; }
.subheader, #content #toctitle, .admonitionblock td.content > .title, .audioblock > .title, .exampleblock > .title, .imageblock > .title, .listingblock > .title, .literalblock > .title, .stemblock > .title, .openblock > .title, .paragraph > .title, .quoteblock > .title, table.tableblock > .title, .verseblock > .title, .videoblock > .title, .dlist > .title, .olist > .title, .ulist > .title, .qlist > .title, .hdlist > .title { line-height: 1.4; color: #7a2518; font-weight: 300; margin-top: 0.2em; margin-bottom: 0.5em; }
abbr, acronym { text-transform: uppercase; font-size: 90%; color: #333333; border-bottom: 1px dotted #dddddd; cursor: help; }
abbr { text-transform: none; }
blockquote { margin: 0 0 1.25em; padding: 0.5625em 1.25em 0 1.1875em; border-left: 3px solid #487c58; }
blockquote cite { display: block; font-size: inherit; color: #454545; }
blockquote cite:before { content: "\2014 \0020"; }
blockquote cite a, blockquote cite a:visited { color: #454545; }
blockquote, blockquote p { line-height: 1.6; color: #6e6e6e; }
@media only screen and (min-width: 768px) {
#toctitle, .sidebarblock > .content > .title { line-height: 1.4; }
#toctitle, .sidebarblock > .content > .title { font-size: 1.6875em; }
}
table { background: white; margin-bottom: 1.25em; border: solid 1px #dddddd; }
table thead, table tfoot { background: whitesmoke; font-weight: bold; }
table thead tr th, table thead tr td, table tfoot tr th, table tfoot tr td { padding: 0.5em 0.625em 0.625em; font-size: inherit; color: #333333; text-align: left; }
table tr th, table tr td { padding: 0.5625em 0.625em; font-size: inherit; color: #333333; }
table tr.even, table tr.alt, table tr:nth-of-type(even) { background: #f9f9f9; }
table thead tr th, table tfoot tr th, table tbody tr td, table tr td, table tfoot tr td { display: table-cell; line-height: 1.6; }
.clearfix:before, .clearfix:after, .float-group:before, .float-group:after { content: " "; display: table; }
.clearfix:after, .float-group:after { clear: both; }
*:not(pre) > code { font-size: inherit; padding: 0; white-space: nowrap; background-color: inherit; border: 0 solid #dddddd; -webkit-border-radius: 4px; border-radius: 4px; text-shadow: none; line-height: 1; }
.keyseq { color: #666666; }
kbd:not(.keyseq) { display: inline-block; color: #333333; font-size: 0.75em; line-height: 1.4; background-color: #f7f7f7; border: 1px solid #ccc; -webkit-border-radius: 3px; border-radius: 3px; -webkit-box-shadow: 0 1px 0 rgba(0, 0, 0, 0.2), 0 0 0 2px white inset; box-shadow: 0 1px 0 rgba(0, 0, 0, 0.2), 0 0 0 2px white inset; margin: -0.15em 0.15em 0 0.15em; padding: 0.2em 0.6em 0.2em 0.5em; vertical-align: middle; white-space: nowrap; }
.keyseq kbd:first-child { margin-left: 0; }
.keyseq kbd:last-child { margin-right: 0; }
.menuseq, .menu { color: #1a1a1a; }
b.button:before, b.button:after { position: relative; top: -1px; font-weight: normal; }
b.button:before { content: "["; padding: 0 3px 0 2px; }
b.button:after { content: "]"; padding: 0 2px 0 3px; }
p a > code:hover { color: #561309; }
#header, #content, #footnotes, #footer { width: 100%; margin-left: auto; margin-right: auto; margin-top: 0; margin-bottom: 0; max-width: 62.5em; *zoom: 1; position: relative; padding-left: 0.9375em; padding-right: 0.9375em; }
#header:before, #header:after, #content:before, #content:after, #footnotes:before, #footnotes:after, #footer:before, #footer:after { content: " "; display: table; }
#header:after, #content:after, #footnotes:after, #footer:after { clear: both; }
#content:before { content: none; }
#header { margin-bottom: 2.5em; }
#header > h1 { color: black; font-weight: 300; border-bottom: 1px solid #d8d8d8; margin-bottom: -28px; padding-bottom: 32px; }
#header span { color: #6e6e6e; }
#header #revnumber { text-transform: capitalize; }
#header br { display: none; }
#header br + span { padding-left: 3px; }
#header br + span:before { content: "\2013 \0020"; }
#header br + span.author { padding-left: 0; }
#header br + span.author:before { content: ", "; }
#toc { border-bottom: 3px double #e5e5e5; padding-top: 1em; padding-bottom: 1.25em; }
#toc > ul { margin-left: 0.25em; }
#toc ul.sectlevel0 > li > a { font-style: italic; }
#toc ul.sectlevel0 ul.sectlevel1 { margin-left: 0; margin-top: 0.5em; margin-bottom: 0.5em; }
#toc ul { font-family: "Open Sans", "DejaVu Sans", "Sans", sans-serif; list-style-type: none; }
#toc a { text-decoration: none; }
#toc a:active { text-decoration: underline; }
#toctitle { color: #7a2518; }
@media only screen and (min-width: 768px) { body.toc2 { padding-left: 15em; padding-right: 0; }
#toc.toc2 { background-color: #fafaf9; position: fixed; width: 15em; left: 0; top: 0; border-right: 1px solid #e5e5e5; border-bottom: 0; z-index: 1000; padding: 1.25em 1em; height: 100%; overflow: auto; }
#toc.toc2 #toctitle { margin-top: 0; font-size: 1.2em; }
#toc.toc2 > ul { font-size: .90em; margin-bottom: 0; }
#toc.toc2 ul ul { margin-left: 0; padding-left: 1em; }
#toc.toc2 ul.sectlevel0 ul.sectlevel1 { padding-left: 0; margin-top: 0.5em; margin-bottom: 0.5em; }
body.toc2.toc-right { padding-left: 0; padding-right: 15em; }
body.toc2.toc-right #toc.toc2 { border-right: 0; border-left: 1px solid #e5e5e5; left: auto; right: 0; } }
@media only screen and (min-width: 1280px) { body.toc2 { padding-left: 20em; padding-right: 0; }
#toc.toc2 { width: 20em; }
#toc.toc2 #toctitle { font-size: 1.375em; }
#toc.toc2 > ul { font-size: 0.95em; }
#toc.toc2 ul ul { padding-left: 1.25em; }
body.toc2.toc-right { padding-left: 0; padding-right: 20em; } }
#content #toc { border-style: solid; border-width: 1px; border-color: #e3e3dd; margin-bottom: 1.25em; padding: 1.25em; background: #fafaf9; border-width: 0; -webkit-border-radius: 4px; border-radius: 4px; }
#content #toc > :first-child { margin-top: 0; }
#content #toc > :last-child { margin-bottom: 0; }
#content #toctitle { font-size: 1.375em; }
#footer { max-width: 100%; background-color: #333333; padding: 1.25em; }
#footer-text { color: #cccccc; line-height: 1.44; }
.audioblock, .imageblock, .literalblock, .listingblock, .stemblock, .verseblock, .videoblock { margin-bottom: 2.5em; }
.admonitionblock td.content > .title, .audioblock > .title, .exampleblock > .title, .imageblock > .title, .listingblock > .title, .literalblock > .title, .stemblock > .title, .openblock > .title, .paragraph > .title, .quoteblock > .title, table.tableblock > .title, .verseblock > .title, .videoblock > .title, .dlist > .title, .olist > .title, .ulist > .title, .qlist > .title, .hdlist > .title { text-rendering: optimizeLegibility; text-align: left; font-family: "Noto Serif", "DejaVu Serif", "Serif", serif; font-weight: normal; font-style: italic; }
table.tableblock > caption.title { white-space: nowrap; overflow: visible; max-width: 0; }
table.tableblock #preamble > .sectionbody > .paragraph:first-of-type p { font-size: inherit; }
.admonitionblock > table { border: 0; background: none; width: 100%; }
.admonitionblock > table td.icon { text-align: center; width: 80px; }
.admonitionblock > table td.icon img { max-width: none; }
.admonitionblock > table td.icon .title { font-weight: 300; text-transform: uppercase; }
.admonitionblock > table td.content { padding-left: 0; padding-right: 1.25em; color: #6e6e6e; }
.admonitionblock > table td.content > :last-child > :last-child { margin-bottom: 0; }
.exampleblock > .content { border-style: solid; border-width: 1px; border-color: #e6e6e6; margin-bottom: 1.25em; padding: 1.25em; background: white; -webkit-border-radius: 4px; border-radius: 4px; }
.exampleblock > .content > :first-child { margin-top: 0; }
.exampleblock > .content > :last-child { margin-bottom: 0; }
.exampleblock > .content h1, .exampleblock > .content h2, .exampleblock > .content h3, .exampleblock > .content #toctitle, .sidebarblock.exampleblock > .content > .title, .exampleblock > .content h4, .exampleblock > .content h5, .exampleblock > .content h6, .exampleblock > .content p { color: #333333; }
.exampleblock > .content h1, .exampleblock > .content h2, .exampleblock > .content h3, .exampleblock > .content #toctitle, .sidebarblock.exampleblock > .content > .title, .exampleblock > .content h4, .exampleblock > .content h5, .exampleblock > .content h6 { line-height: 1; margin-bottom: 0.625em; }
.exampleblock > .content h1.subheader, .exampleblock > .content h2.subheader, .exampleblock > .content h3.subheader, .exampleblock > .content .subheader#toctitle, .sidebarblock.exampleblock > .content > .subheader.title, .exampleblock > .content h4.subheader, .exampleblock > .content h5.subheader, .exampleblock > .content h6.subheader { line-height: 1.4; }
.exampleblock.result > .content { -webkit-box-shadow: 0 1px 8px #e3e3dd; box-shadow: 0 1px 8px #e3e3dd; }
.sidebarblock { border-style: solid; border-width: 1px; border-color: #e3e3dd; margin-top: -1.0em; margin-bottom: 1.6em; margin-left: 1em; padding: .5em; background: #F1F3F5; -webkit-border-radius: 4px; border-radius: 4px; overflow-x: auto; float: right; width: 40%; }
.sidebarblock > :first-child { margin-top: 0; }
.sidebarblock > :last-child { margin-bottom: 0; }
.sidebarblock h1, .sidebarblock h2, .sidebarblock h3, .sidebarblock #toctitle, .sidebarblock > .content > .title, .sidebarblock h4, .sidebarblock h5, .sidebarblock h6, .sidebarblock p { color: #333333; }
.sidebarblock h1, .sidebarblock h2, .sidebarblock h3, .sidebarblock #toctitle, .sidebarblock > .content > .title, .sidebarblock h4, .sidebarblock h5, .sidebarblock h6 { line-height: 1; margin-bottom: 0.625em; }
.sidebarblock h1.subheader, .sidebarblock h2.subheader, .sidebarblock h3.subheader, .sidebarblock .subheader#toctitle, .sidebarblock > .content > .subheader.title, .sidebarblock h4.subheader, .sidebarblock h5.subheader, .sidebarblock h6.subheader { line-height: 1.4; }
.sidebarblock > .content > .title { color: inherit; font-size: 28px; font-weight: 500; margin-top: 0; line-height: 1.6; }
.width50 { width: 50% ! important}
.exampleblock > .content > :last-child > :last-child, .exampleblock > .content .olist > ol > li:last-child > :last-child, .exampleblock > .content .ulist > ul > li:last-child > :last-child, .exampleblock > .content .qlist > ol > li:last-child > :last-child, .sidebarblock > .content > :last-child > :last-child, .sidebarblock > .content .olist > ol > li:last-child > :last-child, .sidebarblock > .content .ulist > ul > li:last-child > :last-child, .sidebarblock > .content .qlist > ol > li:last-child > :last-child { margin-bottom: 0; }
.literalblock pre, .literalblock pre[class], .listingblock pre, .listingblock pre[class] { border: 0px; background-color: #F0F3F5; -webkit-border-radius: 5px; border-radius: 5px; padding: 1.5em 2.5em; word-wrap: break-word; }
.literalblock pre.nowrap, .literalblock pre[class].nowrap, .listingblock pre.nowrap, .listingblock pre[class].nowrap { overflow-x: auto; white-space: pre; word-wrap: normal; }
.literalblock pre > code, .literalblock pre[class] > code, .listingblock pre > code, .listingblock pre[class] > code { display: block; }
.listingblock > .content { position: relative; }
.listingblock:hover code[class*=" language-"]:before { text-transform: uppercase; font-size: 0.9em; color: #999; position: absolute; top: 0.375em; right: 0.375em; }
.listingblock:hover code.asciidoc:before { content: "asciidoc"; }
.listingblock:hover code.clojure:before { content: "clojure"; }
.listingblock:hover code.css:before { content: "css"; }
.listingblock:hover code.go:before { content: "go"; }
.listingblock:hover code.groovy:before { content: "groovy"; }
.listingblock:hover code.html:before { content: "html"; }
.listingblock:hover code.java:before { content: "java"; }
.listingblock:hover code.javascript:before { content: "javascript"; }
.listingblock:hover code.python:before { content: "python"; }
.listingblock:hover code.ruby:before { content: "ruby"; }
.listingblock:hover code.sass:before { content: "sass"; }
.listingblock:hover code.scss:before { content: "scss"; }
.listingblock:hover code.xml:before { content: "xml"; }
.listingblock:hover code.yaml:before { content: "yaml"; }
.listingblock.terminal pre .command:before { content: attr(data-prompt); padding-right: 0.5em; color: #999; }
.listingblock.terminal pre .command:not([data-prompt]):before { content: '$'; }
table.pyhltable { border: 0; margin-bottom: 0; }
table.pyhltable td { vertical-align: top; padding-top: 0; padding-bottom: 0; }
table.pyhltable td.code { padding-left: .75em; padding-right: 0; }
.highlight.pygments .lineno, table.pyhltable td:not(.code) { color: #999; padding-left: 0; padding-right: .5em; border-right: 1px solid #d8d8d8; }
.highlight.pygments .lineno { display: inline-block; margin-right: .25em; }
table.pyhltable .linenodiv { background-color: transparent !important; padding-right: 0 !important; }
.quoteblock { margin: 0 0 1.25em 0; padding: 0.5625em 1.25em 0 1.1875em; border-left: 3px solid #487c58; }
.quoteblock blockquote { margin: 0 0 1.25em 0; padding: 0 0 0.625em 0; border: 0; }
.quoteblock blockquote > .paragraph:last-child p { margin-bottom: 0; }
.quoteblock .attribution { margin-top: -0.625em; padding-bottom: 0.625em; font-size: inherit; color: #454545; line-height: 1.6; }
.quoteblock .attribution br { display: none; }
.quoteblock .attribution cite { display: block; }
table.tableblock { max-width: 100%; }
table.tableblock td .paragraph:last-child p > p:last-child, table.tableblock th > p:last-child, table.tableblock td > p:last-child { margin-bottom: 0; }
table.spread { width: 100%; }
table.tableblock, th.tableblock, td.tableblock { border: 0 solid #dddddd; }
table.grid-all th.tableblock, table.grid-all td.tableblock { border-width: 0 1px 1px 0; }
table.grid-all tfoot > tr > th.tableblock, table.grid-all tfoot > tr > td.tableblock { border-width: 1px 1px 0 0; }
table.grid-cols th.tableblock, table.grid-cols td.tableblock { border-width: 0 1px 0 0; }
table.grid-all * > tr > .tableblock:last-child, table.grid-cols * > tr > .tableblock:last-child { border-right-width: 0; }
table.grid-rows th.tableblock, table.grid-rows td.tableblock { border-width: 0 0 1px 0; }
table.grid-all tbody > tr:last-child > th.tableblock, table.grid-all tbody > tr:last-child > td.tableblock, table.grid-all thead:last-child > tr > th.tableblock, table.grid-rows tbody > tr:last-child > th.tableblock, table.grid-rows tbody > tr:last-child > td.tableblock, table.grid-rows thead:last-child > tr > th.tableblock { border-bottom-width: 0; }
table.grid-rows tfoot > tr > th.tableblock, table.grid-rows tfoot > tr > td.tableblock { border-width: 1px 0 0 0; }
table.frame-all { border-width: 1px; }
table.frame-sides { border-width: 0 1px; }
table.frame-topbot { border-width: 1px 0; }
th.halign-left, td.halign-left { text-align: left; }
th.halign-right, td.halign-right { text-align: right; }
th.halign-center, td.halign-center { text-align: center; }
th.valign-top, td.valign-top { vertical-align: top; }
th.valign-bottom, td.valign-bottom { vertical-align: bottom; }
th.valign-middle, td.valign-middle { vertical-align: middle; }
table thead th, table tfoot th { font-weight: bold; }
tbody tr th { display: table-cell; line-height: 1.6; background: whitesmoke; }
tbody tr th, tbody tr th p, tfoot tr th, tfoot tr th p { color: #333333; font-weight: bold; }
td > div.verse { white-space: pre; }
ul.unstyled, ol.unnumbered, ul.checklist, ul.none { list-style-type: none; }
ul.unstyled, ol.unnumbered, ul.checklist { margin-left: 0.625em; }
ul.checklist li > p:first-child > .fa-check-square-o:first-child, ul.checklist li > p:first-child > input[type="checkbox"]:first-child { margin-right: 0.25em; }
ul.checklist li > p:first-child > input[type="checkbox"]:first-child { position: relative; top: 1px; }
ul.inline { margin: 0 auto 0.625em auto; margin-left: -1.375em; margin-right: 0; padding: 0; list-style: none; overflow: hidden; }
ul.inline > li { list-style: none; float: left; margin-left: 1.375em; display: block; }
ul.inline > li > * { display: block; }
.unstyled dl dt { font-weight: normal; font-style: normal; }
ol.arabic { list-style-type: decimal; }
ol.decimal { list-style-type: decimal-leading-zero; }
ol.loweralpha { list-style-type: lower-alpha; }
ol.upperalpha { list-style-type: upper-alpha; }
ol.lowerroman { list-style-type: lower-roman; }
ol.upperroman { list-style-type: upper-roman; }
ol.lowergreek { list-style-type: lower-greek; }
.hdlist > table, .colist > table { border: 0; background: none; }
.hdlist > table > tbody > tr, .colist > table > tbody > tr { background: none; }
td.hdlist1 { padding-right: .75em; font-weight: bold; }
td.hdlist1, td.hdlist2 { vertical-align: top; }
.literalblock + .colist, .listingblock + .colist { margin-top: -0.5em; }
.colist > table tr > td:first-of-type { padding: 0 .75em; line-height: 1; }
.colist > table tr > td:last-of-type { padding: 0.25em 0; }
.qanda > ol > li > p > em:only-child { color: #1d4b8f; }
.thumb, .th { line-height: 0; display: inline-block; border: solid 4px white; -webkit-box-shadow: 0 0 0 1px #dddddd; box-shadow: 0 0 0 1px #dddddd; }
.imageblock.left, .imageblock[style*="float: left"] { margin: 0.25em 0.625em 1.25em 0; }
.imageblock.right, .imageblock[style*="float: right"] { margin: 0.25em 0 1.25em 0.625em; }
.imageblock > .title { margin-bottom: 0; }
.imageblock.thumb, .imageblock.th { border-width: 6px; }
.imageblock.thumb > .title, .imageblock.th > .title { padding: 0 0.125em; }
.image.left, .image.right { margin-top: 0.25em; margin-bottom: 0.25em; display: inline-block; line-height: 0; }
.image.left { margin-right: 0.625em; }
.image.right { margin-left: 0.625em; }
a.image { text-decoration: none; }
span.footnote, span.footnoteref { vertical-align: super; font-size: 0.875em; }
span.footnote a, span.footnoteref a { text-decoration: none; }
span.footnote a:active, span.footnoteref a:active { text-decoration: underline; }
#footnotes { padding-top: 0.75em; padding-bottom: 0.75em; margin-bottom: 0.625em; }
#footnotes hr { width: 20%; min-width: 6.25em; margin: -.25em 0 .75em 0; border-width: 1px 0 0 0; }
#footnotes .footnote { padding: 0 0.375em; line-height: 1.3; font-size: 0.875em; margin-left: 1.2em; text-indent: -1.2em; margin-bottom: .2em; }
#footnotes .footnote a:first-of-type { font-weight: bold; text-decoration: none; }
#footnotes .footnote:last-of-type { margin-bottom: 0; }
#content #footnotes { margin-top: -0.625em; margin-bottom: 0; padding: 0.75em 0; }
.gist .file-data > table { border: none; background: #fff; width: 100%; margin-bottom: 0; }
.gist .file-data > table td.line-data { width: 99%; }
div.unbreakable { page-break-inside: avoid; }
.replaceable { font-style: italic; font-color: inherit; font-family: inherit; }
.parameter { font-style: italic; font-family: monospace; }
.userinput { font-weight: bold; font-family: monospace; }
.envar { font-weight: bold; font-family: monospace; font-size: 90%; }
.sysitem { font-weight: bold; font-size: 90%; }
.package { font-weight: bold; font-size: 90%; }
.filename { font-weight: bold; font-style: italic; font-size: 90%; }
.big { font-size: larger; }
.small { font-size: smaller; }
.underline { text-decoration: underline; }
.overline { text-decoration: overline; }
.line-through { text-decoration: line-through; }
.aqua { color: #00bfbf; }
.aqua-background { background-color: #00fafa; }
.black { color: black; }
.black-background { background-color: black; }
.blue { color: #0000bf; }
.blue-background { background-color: #0000fa; }
.fuchsia { color: #bf00bf; }
.fuchsia-background { background-color: #fa00fa; }
.gray { color: #606060; }
.gray-background { background-color: #7d7d7d; }
.green { color: #006000; }
.green-background { background-color: #007d00; }
.lime { color: #00bf00; }
.lime-background { background-color: #00fa00; }
.maroon { color: #600000; }
.maroon-background { background-color: #7d0000; }
.navy { color: #000060; }
.navy-background { background-color: #00007d; }
.olive { color: #606000; }
.olive-background { background-color: #7d7d00; }
.purple { color: #600060; }
.purple-background { background-color: #7d007d; }
.red { color: #bf0000; }
.red-background { background-color: #fa0000; }
.silver { color: #909090; }
.silver-background { background-color: #bcbcbc; }
.teal { color: #006060; }
.teal-background { background-color: #007d7d; }
.white { color: #bfbfbf; }
.white-background { background-color: #fafafa; }
.yellow { color: #bfbf00; }
.yellow-background { background-color: #fafa00; }
span.icon > .fa { cursor: default; }
.admonitionblock td.icon [class^="fa icon-"] { font-size: 2.5em; cursor: default; }
.admonitionblock td.icon .icon-note:before { content: "\f05a"; color: #4E9FDD; }
.admonitionblock td.icon .icon-tip:before { content: "\f0eb"; color: #2C8596; }
.admonitionblock td.icon .icon-warning:before { content: "\f071"; color: #ec7a08; }
.admonitionblock td.icon .icon-caution:before { content: "\f06d"; color: #ec7a08; }
.admonitionblock td.icon .icon-important:before { content: "\f06a"; color: #c00; }
.conum[data-value] { display: inline-block; color: white !important; background-color: #333333; -webkit-border-radius: 100px; border-radius: 100px; text-align: center; width: 20px; height: 20px; font-size: 12px; line-height: 20px; font-family: "Open Sans", "Sans", sans-serif; font-style: normal; font-weight: bold; text-indent: -1px; }
.conum[data-value] * { color: white !important; }
.conum[data-value] + b { display: none; }
.conum[data-value]:after { content: attr(data-value); }
pre .conum[data-value] { position: relative; top: -2px; }
b.conum * { color: inherit !important; }
.conum:not([data-value]):empty { display: none; }
.print-only { display: none !important; }
@media print { @page { margin: 1.25cm 0.75cm; }
* { -webkit-box-shadow: none !important; box-shadow: none !important; text-shadow: none !important; }
a, a:visited { color: inherit !important; text-decoration: underline !important; }
a[href^="http:"]:after, a[href^="https:"]:after { content: " (" attr(href) ")"; }
a[href^="#"], a[href^="#"]:visited, a[href^="mailto:"], a[href^="mailto:"]:visited { text-decoration: none !important; }
abbr[title]:after { content: " (" attr(title) ")"; }
pre, blockquote { page-break-inside: avoid; }
code { color: #191919; }
thead { display: table-header-group; }
tr, img { page-break-inside: avoid; }
img { max-width: 100% !important; }
p { orphans: 3; widows: 3; }
h2, h3, #toctitle, .sidebarblock > .content > .title, #toctitle, .sidebarblock > .content > .title { page-break-after: avoid; }
#toc, .sidebarblock { background: none !important; }
#toc { border-bottom: 1px solid #d8d8d8 !important; padding-bottom: 0 !important; }
.sect1 { padding-bottom: 0 !important; }
.sect1 + .sect1 { border: none !important; }
body.book #header { text-align: center; }
body.book #header > h1 { border: none !important; margin: 2.5em 0 1em 0; padding: 0; }
body.book #header span { line-height: 1.6; }
body.book #header br { display: block; }
body.book #header br + span { padding-left: 0; }
body.book #header br + span:before { content: none !important; }
body.book #toc { border: none !important; text-align: left !important; padding: 0 !important; }
#footer { background: none !important; }
#footer-text { color: #333333 !important; }
.hide-on-print { display: none !important; }
.print-only { display: block !important; }
.hide-for-print { display: none !important; }
.show-for-print { display: inherit !important; } }
.corner-ribbon{
width: 16em;
background: #3c6eb4 ;
position: absolute;
top: 3em;
right: -4em;
text-align: center;
line-height: 5ex;
color: #dedede;
transform: rotate(45deg);
-webkit-transform: rotate(45deg);
z-index: 999;
}
.corner-ribbon a { color: #FFFFFF; }

View file

@ -1,348 +0,0 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta content="IE=edge" http-equiv="X-UA-Compatible">
<meta content="width=device-width, initial-scale=1.0" name="viewport">
<title>Defensive Coding Guide | Defensive Coding Guide | Revision History</title>
<!-- Bootstrap -->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css">
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap-theme.min.css">
<!-- Overpass Font -->
<link rel="stylesheet" href="https://overpass-30e2.kxcdn.com/overpass.css">
<link href="../../master/_stylesheets/asciibinder.css" rel="stylesheet" />
<!-- HTML5 shim and Respond.js for IE8 support of HTML5 elements and media queries -->
<!-- WARNING: Respond.js doesn't work if you view the page via file:// -->
<!--[if lt IE 9]>
<script src="https://oss.maxcdn.com/html5shiv/3.7.2/html5shiv.min.js"></script>
<script src="https://oss.maxcdn.com/respond/1.4.2/respond.min.js"></script>
<![endif]-->
<link href="../../master/_images/favicon32x32.png" rel="shortcut icon" type="text/css">
<!--[if IE]><link rel="shortcut icon" href="../../master/_images/favicon.ico"><![endif]-->
<meta content="AsciiBinder" name="application-name">
</head>
<body>
<div class="navbar navbar-default" role="navigation">
<div class="container-fluid">
<div class="navbar-header">
<a class="navbar-brand" href="https://docs.fedoraproject.org/"><img alt="Fedora Documentation" src="../../master/_images/fedora.svg"></a>
</div>
</div>
</div>
<div class="container">
<p class="toggle-nav visible-xs pull-left">
<button class="btn btn-default btn-sm" type="button" data-toggle="offcanvas">Toggle nav</button>
</p>
<ol class="breadcrumb">
<li class="sitename">
<a href="../../index.html">Home</a>
</li>
<li class="hidden-xs active">
<a href="../en-US/index.html">Defensive Coding Guide </a>
</li>
<li class="hidden-xs active">
<a href="../en-US/index.html">Defensive Coding Guide</a>
</li>
<li class="hidden-xs active">
Revision History
</li>
</ol>
<div class="row row-offcanvas row-offcanvas-left">
<div class="col-xs-8 col-sm-3 col-md-3 sidebar sidebar-offcanvas">
<ul class="nav nav-sidebar">
<li class="nav-header">
<a class="" href="#" data-toggle="collapse" data-target="#topicGroup0">
<span id="tgSpan0" class="fa fa-angle-down"></span>Defensive Coding Guide
</a>
<ul id="topicGroup0" class="collapse in list-unstyled">
<li><a class="" href="../en-US/index.html">Book Information</a></li>
<li class="nav-header">
<a class="" href="#" data-toggle="collapse" data-target="#topicSubGroup-0-1">
<span id="sgSpan-0-1" class="fa fa-caret-right"></span>&nbsp;Programming Languages
</a>
<ul id="topicSubGroup-0-1" class="nav-tertiary list-unstyled collapse">
<li><a class="" href="../en-US/programming-languages/C.html">The C Programming Language</a></li>
<li><a class="" href="../en-US/programming-languages/CXX.html">The C++ Programming&nbsp;Language</a></li>
<li><a class="" href="../en-US/programming-languages/Java.html">The Java Programming Language</a></li>
<li><a class="" href="../en-US/programming-languages/Python.html">The Python Programming Language</a></li>
<li><a class="" href="../en-US/programming-languages/Shell.html">Shell Programming and bash</a></li>
<li><a class="" href="../en-US/programming-languages/Go.html">The Go Programming Language</a></li>
<li><a class="" href="../en-US/programming-languages/Vala.html">The Vala Programming Language</a></li>
</ul>
</li>
<li class="nav-header">
<a class="" href="#" data-toggle="collapse" data-target="#topicSubGroup-0-2">
<span id="sgSpan-0-2" class="fa fa-caret-right"></span>&nbsp;Specific Programming Tasks
</a>
<ul id="topicSubGroup-0-2" class="nav-tertiary list-unstyled collapse">
<li><a class="" href="../en-US/tasks/Tasks-Library_Design.html">Library Design</a></li>
<li><a class="" href="../en-US/tasks/Tasks-Descriptors.html">File Descriptor Management</a></li>
<li><a class="" href="../en-US/tasks/Tasks-File_System.html">File System Manipulation</a></li>
<li><a class="" href="../en-US/tasks/Tasks-Temporary_Files.html">Temporary Files</a></li>
<li><a class="" href="../en-US/tasks/Tasks-Processes.html">Processes</a></li>
<li><a class="" href="../en-US/tasks/Tasks-Serialization.html">Serialization and Deserialization</a></li>
<li><a class="" href="../en-US/tasks/Tasks-Cryptography.html">Cryptography</a></li>
<li><a class="" href="../en-US/tasks/Tasks-Packaging.html">RPM Packaging</a></li>
</ul>
</li>
<li class="nav-header">
<a class="" href="#" data-toggle="collapse" data-target="#topicSubGroup-0-3">
<span id="sgSpan-0-3" class="fa fa-caret-right"></span>&nbsp;Implementing Security Features
</a>
<ul id="topicSubGroup-0-3" class="nav-tertiary list-unstyled collapse">
<li><a class="" href="../en-US/features/Features-Authentication.html">Authentication and Authorization</a></li>
<li><a class="" href="../en-US/features/Features-TLS.html">Transport Layer Security (TLS)</a></li>
<li><a class="" href="../en-US/features/Features-HSM.html">Hardware Security Modules and Smart Cards</a></li>
</ul>
</li>
<li><a class=" active" href="../en-US/Revision_History.html">Revision History</a></li>
</ul>
</li>
</ul>
</div>
<div class="col-xs-12 col-sm-9 col-md-9 main">
<div class="page-header">
<h2>Revision History</h2>
</div>
<div class="dlist">
<dl>
<dt class="hdlist1"><code>1.5</code></dt>
<dd>
<p>Fri Dec 1 2017, Mirek Jahoda (<a href="mailto:mjahoda@redhat.com">mjahoda@redhat.com</a>)</p>
<div class="ulist">
<ul>
<li>
<p>First release in AsciiDoc</p>
</li>
<li>
<p>Many updates in the crypto-related sections</p>
</li>
<li>
<p>Grammar and typography fixes</p>
</li>
</ul>
</div>
</dd>
<dt class="hdlist1"><code>1.3-1</code></dt>
<dd>
<p>Mon Oct 13 2014, Florian Weimer (<a href="mailto:fweimer@redhat.com">fweimer@redhat.com</a>)</p>
<div class="ulist">
<ul>
<li>
<p>Go: Mention default value handling in deserialization</p>
</li>
<li>
<p>Shell: New chapter</p>
</li>
</ul>
</div>
</dd>
<dt class="hdlist1"><code>1.2-1</code></dt>
<dd>
<p>Wed Jul 16 2014, Florian Weimer (<a href="mailto:fweimer@redhat.com">fweimer@redhat.com</a>)</p>
<div class="ulist">
<ul>
<li>
<p>C: Corrected the <code>strncat</code> example</p>
</li>
<li>
<p>C: Mention mixed signed/unsigned comparisons</p>
</li>
<li>
<p>C: Unsigned overflow checking example</p>
</li>
<li>
<p>C++: <code>operator new[]</code> has been fixed in GCC</p>
</li>
<li>
<p>C++: Additional material on <code>std::string</code>, iterators</p>
</li>
<li>
<p>OpenSSL: Mention <code class="command">openssl genrsa</code> entropy issue</p>
</li>
<li>
<p>Packaging: X.509 key generation</p>
</li>
<li>
<p>Go, Vala: Add short chapters</p>
</li>
<li>
<p>Serialization: Notes on fragmentation and reassembly</p>
</li>
</ul>
</div>
</dd>
<dt class="hdlist1"><code>1.1-1</code></dt>
<dd>
<p>Tue Aug 27 2013, Eric Christensen (<a href="mailto:sparks@redhat.com">sparks@redhat.com</a>)</p>
<div class="ulist">
<ul>
<li>
<p>Add a chapter which covers some Java topics.</p>
</li>
<li>
<p>Deserialization: Warn about Java&#8217;s java.beans.XMLDecoder.</p>
</li>
<li>
<p>C: Correct the advice on array allocation
(<a href="https://bugzilla.redhat.com/show_bug.cgi?id=995595">bug 995595</a>).</p>
</li>
<li>
<p>C: Add material on global variables.</p>
</li>
</ul>
</div>
</dd>
<dt class="hdlist1"><code>1.0-1</code></dt>
<dd>
<p>Thu May 09 2013, Eric Christensen (<a href="mailto:sparks@redhat.com">sparks@redhat.com</a>)</p>
<div class="ulist">
<ul>
<li>
<p>Added more C and C++ examples.</p>
</li>
<li>
<p>TLS Client NSS: Rely on NSS 3.14 cipher suite defaults.</p>
</li>
</ul>
</div>
</dd>
<dt class="hdlist1"><code>0-1</code></dt>
<dd>
<p>Thu Mar 7 2013, Eric Christensen (<a href="mailto:sparks@redhat.com">sparks@redhat.com</a>)</p>
<div class="ulist">
<ul>
<li>
<p>Initial publication.</p>
</li>
</ul>
</div>
</dd>
</dl>
</div>
</div>
</div>
</div>
<div id="bottom" class="text-muted py-3" >
<div class="foot">
<div class="container">
<div class="row footerlinks">
<div class="col-sm-3 col-xs-6 widget">
<h3 class="widget-title">About</h3>
<div class="widget-body">
<dl>
<dd><a href="https://fedoraproject.org/wiki/Overview">About Fedora</a></dd>
<dd><a href="https://getfedora.org/en/sponsors">Sponsors</a></dd>
<dd><a href="https://fedoramagazine.org">Fedora Magazine</a></dd>
<dd><a href="https://fedoraproject.org/wiki/Legal:Main#Legal">Legal</a></dd>
</dl>
<ul class="list-inline">
<li>
<a href="https://www.facebook.com/TheFedoraProject" class="btn-social btn-outline"><i class="fa fa-fw fa-facebook"></i></a>
</li>
<li>
<a href="https://plus.google.com/112917221531140868607" class="btn-social btn-outline"><i class="fa fa-fw fa-google-plus"></i></a>
</li>
<li>
<a href="https://twitter.com/fedora" class="btn-social btn-outline"><i class="fa fa-fw fa-twitter"></i></a>
</li>
</ul>
</div>
</div>
<div class="col-sm-3 col-xs-6 widget">
<h3 class="widget-title uppercase">Download</h3>
<div class="widget-body">
<dl>
<dd><a href="https://getfedora.org/en/workstation/download">Get Fedora Workstation</a></dd>
<dd><a href="https://getfedora.org/en/server/download">Get Fedora Server</a></dd>
<dd><a href="https://getfedora.org/en/atomic/download">Get Fedora Atomic</a></dd>
<dd><a href="https://spins.fedoraproject.org">Fedora Spins</a></dd>
<dd><a href="https://labs.fedoraproject.org">Fedora Labs</a></dd>
<dd><a href="https://arm.fedoraproject.org">Fedora ARM<span class="sup">&reg;</span></a></dd>
<dd><a href="https://alt.fedoraproject.org/">Alternative Downloads</a></dd>
</dl>
</div>
</div>
<div class="col-sm-3 col-xs-6 widget">
<h3 class="widget-title">Support</h3>
<div class="widget-body">
<dl>
<dd><a href="https://fedoraproject.org/wiki/Communicating_and_getting_help">Get Help</a></dd>
<dd><a href="https://ask.fedoraproject.org/">Ask Fedora</a></dd>
<dd><a href="https://fedoraproject.org/wiki/Common_F27_bugs">Common Bugs</a></dd>
<dd><a href="https://developer.fedoraproject.org/">Fedora Developer Portal</a></dd>
<dd><a href="https://docs.fedoraproject.org/f27/install-guide/index.html">Installation Guide</a></dd>
</dl>
</div>
</div>
<div class="col-sm-3 col-xs-6 widget">
<h3 class="widget-title">Join</h3>
<div class="widget-body">
<dl>
<dd><a href="https://fedoraproject.org/wiki/Join">Join Fedora</a></dd>
<dd><a href="http://fedoraplanet.org">Planet Fedora</a></dd>
<dd><a href="https://fedoraproject.org/wiki/SIGs">Fedora SIGs</a></dd>
<dd><a href="https://admin.fedoraproject.org/accounts/">Fedora Account System</a></dd>
<dd><a href="https://fedoracommunity.org/">Fedora Community</a></dd>
</dl>
</div>
</div>
</div> <!-- /row of widgets -->
<div class="row">
<div class="col-md-2">
<div class="widget-body">
<a href="https://www.redhat.com/"><img class="rh-logo" src="../../master/_images/redhat-logo.png" alt="Red Hat Logo" /></a>
</div>
</div>
<div class="col-md-7">
<div class="widget-body">
<p class="sponsor">Fedora is sponsored by Red Hat.</p>
<p class="sponsor"><a href="https://www.redhat.com/en/technologies/linux-platforms/articles/relationship-between-fedora-and-rhel">Learn more about the relationship between Red Hat and Fedora &raquo;</a></p>
<p class="copy">&copy; 2017 Red Hat, Inc. and others. Please send any comments or corrections to the <a href="https://pagure.io/fedora-docs/docs-fp-o">documentation team</a></p>
</div>
</div>
</div> <!-- /row of widgets -->
</div>
</div>
</div>
<!-- jQuery (necessary for Bootstrap's JavaScript plugins) -->
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>
<!-- Latest compiled and minified JavaScript -->
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/js/bootstrap.min.js"></script>
<script src="../../master/_javascripts/bootstrap-offcanvas.js" type="text/javascript"></script>
<script type="text/javascript">
/*<![CDATA[*/
$(document).ready(function() {
$("[id^='topicGroup']").on('show.bs.collapse', function (event) {
if (!($(event.target).attr('id').match(/^topicSubGroup/))) {
$(this).parent().find("[id^='tgSpan']").toggleClass("fa-angle-right fa-angle-down");
}
});
$("[id^='topicGroup']").on('hide.bs.collapse', function (event) {
if (!($(event.target).attr('id').match(/^topicSubGroup/))) {
$(this).parent().find("[id^='tgSpan']").toggleClass("fa-angle-right fa-angle-down");
}
});
$("[id^='topicSubGroup']").on('show.bs.collapse', function () {
$(this).parent().find("[id^='sgSpan']").toggleClass("fa-caret-right fa-caret-down");
});
$("[id^='topicSubGroup']").on('hide.bs.collapse', function () {
$(this).parent().find("[id^='sgSpan']").toggleClass("fa-caret-right fa-caret-down");
});
});
/*]]>*/
</script>
</body>
</html>

View file

@ -1,410 +0,0 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta content="IE=edge" http-equiv="X-UA-Compatible">
<meta content="width=device-width, initial-scale=1.0" name="viewport">
<title>Defensive Coding Guide | Defensive Coding Guide | Implementing Security Features | Authentication and Authorization</title>
<!-- Bootstrap -->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css">
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap-theme.min.css">
<!-- Overpass Font -->
<link rel="stylesheet" href="https://overpass-30e2.kxcdn.com/overpass.css">
<link href="../../../master/_stylesheets/asciibinder.css" rel="stylesheet" />
<!-- HTML5 shim and Respond.js for IE8 support of HTML5 elements and media queries -->
<!-- WARNING: Respond.js doesn't work if you view the page via file:// -->
<!--[if lt IE 9]>
<script src="https://oss.maxcdn.com/html5shiv/3.7.2/html5shiv.min.js"></script>
<script src="https://oss.maxcdn.com/respond/1.4.2/respond.min.js"></script>
<![endif]-->
<link href="../../../master/_images/favicon32x32.png" rel="shortcut icon" type="text/css">
<!--[if IE]><link rel="shortcut icon" href="../../../master/_images/favicon.ico"><![endif]-->
<meta content="AsciiBinder" name="application-name">
</head>
<body>
<div class="navbar navbar-default" role="navigation">
<div class="container-fluid">
<div class="navbar-header">
<a class="navbar-brand" href="https://docs.fedoraproject.org/"><img alt="Fedora Documentation" src="../../../master/_images/fedora.svg"></a>
</div>
</div>
</div>
<div class="container">
<p class="toggle-nav visible-xs pull-left">
<button class="btn btn-default btn-sm" type="button" data-toggle="offcanvas">Toggle nav</button>
</p>
<ol class="breadcrumb">
<li class="sitename">
<a href="../../../index.html">Home</a>
</li>
<li class="hidden-xs active">
<a href="../../en-US/index.html">Defensive Coding Guide </a>
</li>
<li class="hidden-xs active">
<a href="../../en-US/index.html">Defensive Coding Guide</a>
</li>
<li class="hidden-xs active"><a href="../../en-US/features/Features-Authentication.html">Implementing Security Features</a></li>
<li class="hidden-xs active">
Authentication and Authorization
</li>
</ol>
<div class="row row-offcanvas row-offcanvas-left">
<div class="col-xs-8 col-sm-3 col-md-3 sidebar sidebar-offcanvas">
<ul class="nav nav-sidebar">
<li class="nav-header">
<a class="" href="#" data-toggle="collapse" data-target="#topicGroup0">
<span id="tgSpan0" class="fa fa-angle-down"></span>Defensive Coding Guide
</a>
<ul id="topicGroup0" class="collapse in list-unstyled">
<li><a class="" href="../../en-US/index.html">Book Information</a></li>
<li class="nav-header">
<a class="" href="#" data-toggle="collapse" data-target="#topicSubGroup-0-1">
<span id="sgSpan-0-1" class="fa fa-caret-right"></span>&nbsp;Programming Languages
</a>
<ul id="topicSubGroup-0-1" class="nav-tertiary list-unstyled collapse">
<li><a class="" href="../../en-US/programming-languages/C.html">The C Programming Language</a></li>
<li><a class="" href="../../en-US/programming-languages/CXX.html">The C++ Programming&nbsp;Language</a></li>
<li><a class="" href="../../en-US/programming-languages/Java.html">The Java Programming Language</a></li>
<li><a class="" href="../../en-US/programming-languages/Python.html">The Python Programming Language</a></li>
<li><a class="" href="../../en-US/programming-languages/Shell.html">Shell Programming and bash</a></li>
<li><a class="" href="../../en-US/programming-languages/Go.html">The Go Programming Language</a></li>
<li><a class="" href="../../en-US/programming-languages/Vala.html">The Vala Programming Language</a></li>
</ul>
</li>
<li class="nav-header">
<a class="" href="#" data-toggle="collapse" data-target="#topicSubGroup-0-2">
<span id="sgSpan-0-2" class="fa fa-caret-right"></span>&nbsp;Specific Programming Tasks
</a>
<ul id="topicSubGroup-0-2" class="nav-tertiary list-unstyled collapse">
<li><a class="" href="../../en-US/tasks/Tasks-Library_Design.html">Library Design</a></li>
<li><a class="" href="../../en-US/tasks/Tasks-Descriptors.html">File Descriptor Management</a></li>
<li><a class="" href="../../en-US/tasks/Tasks-File_System.html">File System Manipulation</a></li>
<li><a class="" href="../../en-US/tasks/Tasks-Temporary_Files.html">Temporary Files</a></li>
<li><a class="" href="../../en-US/tasks/Tasks-Processes.html">Processes</a></li>
<li><a class="" href="../../en-US/tasks/Tasks-Serialization.html">Serialization and Deserialization</a></li>
<li><a class="" href="../../en-US/tasks/Tasks-Cryptography.html">Cryptography</a></li>
<li><a class="" href="../../en-US/tasks/Tasks-Packaging.html">RPM Packaging</a></li>
</ul>
</li>
<li class="nav-header">
<a class="" href="#" data-toggle="collapse" data-target="#topicSubGroup-0-3">
<span id="sgSpan-0-3" class="fa fa-caret-down"></span>&nbsp;Implementing Security Features
</a>
<ul id="topicSubGroup-0-3" class="nav-tertiary list-unstyled collapse in">
<li><a class=" active" href="../../en-US/features/Features-Authentication.html">Authentication and Authorization</a></li>
<li><a class="" href="../../en-US/features/Features-TLS.html">Transport Layer Security (TLS)</a></li>
<li><a class="" href="../../en-US/features/Features-HSM.html">Hardware Security Modules and Smart Cards</a></li>
</ul>
</li>
<li><a class="" href="../../en-US/Revision_History.html">Revision History</a></li>
</ul>
</li>
</ul>
</div>
<div class="col-xs-12 col-sm-9 col-md-9 main">
<div class="page-header">
<h2>Authentication and Authorization</h2>
</div>
<div class="sect1">
<h2 id="sect-Defensive_Coding-Authentication-Server"><a class="anchor" href="#sect-Defensive_Coding-Authentication-Server"></a>Authenticating Servers</h2>
<div class="sectionbody">
<div class="paragraph">
<p>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:</p>
</div>
<div class="ulist">
<ul>
<li>
<p>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.</p>
</li>
<li>
<p>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.</p>
</li>
<li>
<p>On Linux, UNIX domain sockets (of the
<code>PF_UNIX</code> protocol family, sometimes called
<code>PF_LOCAL</code>) are restricted by file system
permissions. If the server socket path is not
world-writable, the server identity cannot be spoofed by
local users.</p>
</li>
<li>
<p>Port numbers less than 1024 (<strong>trusted
ports</strong>) can only be used by
<code>root</code>, 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.)</p>
</li>
</ul>
</div>
<div class="paragraph">
<p>TLS (<a href="#chap-Defensive_Coding-TLS">[chap-Defensive_Coding-TLS]</a>) is the
recommended way for securing connections over untrusted
networks.</p>
</div>
<div class="paragraph">
<p>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.</p>
</div>
</div>
</div>
<div class="sect1">
<h2 id="sect-Defensive_Coding-Authentication-Host_based"><a class="anchor" href="#sect-Defensive_Coding-Authentication-Host_based"></a>Host-based Authentication</h2>
<div class="sectionbody">
<div class="paragraph">
<p>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
<code>/etc/hosts</code>). 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.)</p>
</div>
<div class="paragraph">
<p>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.</p>
</div>
<div class="paragraph">
<p>The names returned by <code>gethostbyaddr</code> and
<code>getnameinfo</code> 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
<code>gethostbyaddr</code> or
<code>getaddrinfo</code> has to be performed. The name
is only valid if the original address is found among the results
of the forward lookup (<strong>double-reverse
lookup</strong>).</p>
</div>
<div class="paragraph">
<p>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.</p>
</div>
<div class="paragraph">
<p>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.</p>
</div>
<div class="paragraph">
<p>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.</p>
</div>
</div>
</div>
<div class="sect1">
<h2 id="sect-Defensive_Coding-Authentication-UNIX_Domain"><a class="anchor" href="#sect-Defensive_Coding-Authentication-UNIX_Domain"></a>UNIX Domain Socket Authentication</h2>
<div class="sectionbody">
<div class="paragraph">
<p>UNIX domain sockets (with address family
<code>AF_UNIX</code> or <code>AF_LOCAL</code>) are
restricted to the local host and offer a special authentication
mechanism: credentials passing.</p>
</div>
<div class="paragraph">
<p>Nowadays, most systems support the
<code>SO_PEERCRED</code> (Linux) or
<code>LOCAL_PEERCRED</code> (FreeBSD) socket options, or
the <code>getpeereid</code> (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.</p>
</div>
<div class="paragraph">
<p>Historically, credentials passing was implemented using
ancillary data in the <code>sendmsg</code> and
<code>recvmsg</code> 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.</p>
</div>
<div class="paragraph">
<p>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
<code>getpwuid</code> (or
<code>getpwuid_r</code>) and
<code>getgrouplist</code>. Using the PID and
information from <code>/proc/PID/status</code> is prone
to race conditions and insecure.</p>
</div>
</div>
</div>
<div class="sect1">
<h2 id="sect-Defensive_Coding-Authentication-Netlink"><a class="anchor" href="#sect-Defensive_Coding-Authentication-Netlink"></a><code>AF_NETLINK</code> Authentication of Origin</h2>
<div class="sectionbody">
<div class="paragraph">
<p>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.</p>
</div>
<div class="paragraph">
<p>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
<code>nl_pid</code> in the <code>sockaddr_nl</code>
structure is <code>0</code>. (This structure can be
obtained using <code>recvfrom</code> or
<code>recvmsg</code>, it is different from the
<code>nlmsghdr</code> structure.) The kernel does not
prevent other processes from sending unicast Netlink messages,
but the <code>nl_pid</code> field in the sender&#8217;s socket
address will be non-zero in such cases.</p>
</div>
<div class="paragraph">
<p>Applications should not use <code>AF_NETLINK</code>
sockets as an IPC mechanism among processes, but prefer UNIX
domain sockets for this tasks.</p>
</div>
</div>
</div>
</div>
</div>
</div>
<div id="bottom" class="text-muted py-3" >
<div class="foot">
<div class="container">
<div class="row footerlinks">
<div class="col-sm-3 col-xs-6 widget">
<h3 class="widget-title">About</h3>
<div class="widget-body">
<dl>
<dd><a href="https://fedoraproject.org/wiki/Overview">About Fedora</a></dd>
<dd><a href="https://getfedora.org/en/sponsors">Sponsors</a></dd>
<dd><a href="https://fedoramagazine.org">Fedora Magazine</a></dd>
<dd><a href="https://fedoraproject.org/wiki/Legal:Main#Legal">Legal</a></dd>
</dl>
<ul class="list-inline">
<li>
<a href="https://www.facebook.com/TheFedoraProject" class="btn-social btn-outline"><i class="fa fa-fw fa-facebook"></i></a>
</li>
<li>
<a href="https://plus.google.com/112917221531140868607" class="btn-social btn-outline"><i class="fa fa-fw fa-google-plus"></i></a>
</li>
<li>
<a href="https://twitter.com/fedora" class="btn-social btn-outline"><i class="fa fa-fw fa-twitter"></i></a>
</li>
</ul>
</div>
</div>
<div class="col-sm-3 col-xs-6 widget">
<h3 class="widget-title uppercase">Download</h3>
<div class="widget-body">
<dl>
<dd><a href="https://getfedora.org/en/workstation/download">Get Fedora Workstation</a></dd>
<dd><a href="https://getfedora.org/en/server/download">Get Fedora Server</a></dd>
<dd><a href="https://getfedora.org/en/atomic/download">Get Fedora Atomic</a></dd>
<dd><a href="https://spins.fedoraproject.org">Fedora Spins</a></dd>
<dd><a href="https://labs.fedoraproject.org">Fedora Labs</a></dd>
<dd><a href="https://arm.fedoraproject.org">Fedora ARM<span class="sup">&reg;</span></a></dd>
<dd><a href="https://alt.fedoraproject.org/">Alternative Downloads</a></dd>
</dl>
</div>
</div>
<div class="col-sm-3 col-xs-6 widget">
<h3 class="widget-title">Support</h3>
<div class="widget-body">
<dl>
<dd><a href="https://fedoraproject.org/wiki/Communicating_and_getting_help">Get Help</a></dd>
<dd><a href="https://ask.fedoraproject.org/">Ask Fedora</a></dd>
<dd><a href="https://fedoraproject.org/wiki/Common_F27_bugs">Common Bugs</a></dd>
<dd><a href="https://developer.fedoraproject.org/">Fedora Developer Portal</a></dd>
<dd><a href="https://docs.fedoraproject.org/f27/install-guide/index.html">Installation Guide</a></dd>
</dl>
</div>
</div>
<div class="col-sm-3 col-xs-6 widget">
<h3 class="widget-title">Join</h3>
<div class="widget-body">
<dl>
<dd><a href="https://fedoraproject.org/wiki/Join">Join Fedora</a></dd>
<dd><a href="http://fedoraplanet.org">Planet Fedora</a></dd>
<dd><a href="https://fedoraproject.org/wiki/SIGs">Fedora SIGs</a></dd>
<dd><a href="https://admin.fedoraproject.org/accounts/">Fedora Account System</a></dd>
<dd><a href="https://fedoracommunity.org/">Fedora Community</a></dd>
</dl>
</div>
</div>
</div> <!-- /row of widgets -->
<div class="row">
<div class="col-md-2">
<div class="widget-body">
<a href="https://www.redhat.com/"><img class="rh-logo" src="../../../master/_images/redhat-logo.png" alt="Red Hat Logo" /></a>
</div>
</div>
<div class="col-md-7">
<div class="widget-body">
<p class="sponsor">Fedora is sponsored by Red Hat.</p>
<p class="sponsor"><a href="https://www.redhat.com/en/technologies/linux-platforms/articles/relationship-between-fedora-and-rhel">Learn more about the relationship between Red Hat and Fedora &raquo;</a></p>
<p class="copy">&copy; 2017 Red Hat, Inc. and others. Please send any comments or corrections to the <a href="https://pagure.io/fedora-docs/docs-fp-o">documentation team</a></p>
</div>
</div>
</div> <!-- /row of widgets -->
</div>
</div>
</div>
<!-- jQuery (necessary for Bootstrap's JavaScript plugins) -->
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>
<!-- Latest compiled and minified JavaScript -->
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/js/bootstrap.min.js"></script>
<script src="../../../master/_javascripts/bootstrap-offcanvas.js" type="text/javascript"></script>
<script type="text/javascript">
/*<![CDATA[*/
$(document).ready(function() {
$("[id^='topicGroup']").on('show.bs.collapse', function (event) {
if (!($(event.target).attr('id').match(/^topicSubGroup/))) {
$(this).parent().find("[id^='tgSpan']").toggleClass("fa-angle-right fa-angle-down");
}
});
$("[id^='topicGroup']").on('hide.bs.collapse', function (event) {
if (!($(event.target).attr('id').match(/^topicSubGroup/))) {
$(this).parent().find("[id^='tgSpan']").toggleClass("fa-angle-right fa-angle-down");
}
});
$("[id^='topicSubGroup']").on('show.bs.collapse', function () {
$(this).parent().find("[id^='sgSpan']").toggleClass("fa-caret-right fa-caret-down");
});
$("[id^='topicSubGroup']").on('hide.bs.collapse', function () {
$(this).parent().find("[id^='sgSpan']").toggleClass("fa-caret-right fa-caret-down");
});
});
/*]]>*/
</script>
</body>
</html>

View file

@ -1,617 +0,0 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta content="IE=edge" http-equiv="X-UA-Compatible">
<meta content="width=device-width, initial-scale=1.0" name="viewport">
<title>Defensive Coding Guide | Defensive Coding Guide | Implementing Security Features | Hardware Security Modules and Smart Cards</title>
<!-- Bootstrap -->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css">
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap-theme.min.css">
<!-- Overpass Font -->
<link rel="stylesheet" href="https://overpass-30e2.kxcdn.com/overpass.css">
<link href="../../../master/_stylesheets/asciibinder.css" rel="stylesheet" />
<!-- HTML5 shim and Respond.js for IE8 support of HTML5 elements and media queries -->
<!-- WARNING: Respond.js doesn't work if you view the page via file:// -->
<!--[if lt IE 9]>
<script src="https://oss.maxcdn.com/html5shiv/3.7.2/html5shiv.min.js"></script>
<script src="https://oss.maxcdn.com/respond/1.4.2/respond.min.js"></script>
<![endif]-->
<link href="../../../master/_images/favicon32x32.png" rel="shortcut icon" type="text/css">
<!--[if IE]><link rel="shortcut icon" href="../../../master/_images/favicon.ico"><![endif]-->
<meta content="AsciiBinder" name="application-name">
</head>
<body>
<div class="navbar navbar-default" role="navigation">
<div class="container-fluid">
<div class="navbar-header">
<a class="navbar-brand" href="https://docs.fedoraproject.org/"><img alt="Fedora Documentation" src="../../../master/_images/fedora.svg"></a>
</div>
</div>
</div>
<div class="container">
<p class="toggle-nav visible-xs pull-left">
<button class="btn btn-default btn-sm" type="button" data-toggle="offcanvas">Toggle nav</button>
</p>
<ol class="breadcrumb">
<li class="sitename">
<a href="../../../index.html">Home</a>
</li>
<li class="hidden-xs active">
<a href="../../en-US/index.html">Defensive Coding Guide </a>
</li>
<li class="hidden-xs active">
<a href="../../en-US/index.html">Defensive Coding Guide</a>
</li>
<li class="hidden-xs active"><a href="../../en-US/features/Features-Authentication.html">Implementing Security Features</a></li>
<li class="hidden-xs active">
Hardware Security Modules and Smart Cards
</li>
</ol>
<div class="row row-offcanvas row-offcanvas-left">
<div class="col-xs-8 col-sm-3 col-md-3 sidebar sidebar-offcanvas">
<ul class="nav nav-sidebar">
<li class="nav-header">
<a class="" href="#" data-toggle="collapse" data-target="#topicGroup0">
<span id="tgSpan0" class="fa fa-angle-down"></span>Defensive Coding Guide
</a>
<ul id="topicGroup0" class="collapse in list-unstyled">
<li><a class="" href="../../en-US/index.html">Book Information</a></li>
<li class="nav-header">
<a class="" href="#" data-toggle="collapse" data-target="#topicSubGroup-0-1">
<span id="sgSpan-0-1" class="fa fa-caret-right"></span>&nbsp;Programming Languages
</a>
<ul id="topicSubGroup-0-1" class="nav-tertiary list-unstyled collapse">
<li><a class="" href="../../en-US/programming-languages/C.html">The C Programming Language</a></li>
<li><a class="" href="../../en-US/programming-languages/CXX.html">The C++ Programming&nbsp;Language</a></li>
<li><a class="" href="../../en-US/programming-languages/Java.html">The Java Programming Language</a></li>
<li><a class="" href="../../en-US/programming-languages/Python.html">The Python Programming Language</a></li>
<li><a class="" href="../../en-US/programming-languages/Shell.html">Shell Programming and bash</a></li>
<li><a class="" href="../../en-US/programming-languages/Go.html">The Go Programming Language</a></li>
<li><a class="" href="../../en-US/programming-languages/Vala.html">The Vala Programming Language</a></li>
</ul>
</li>
<li class="nav-header">
<a class="" href="#" data-toggle="collapse" data-target="#topicSubGroup-0-2">
<span id="sgSpan-0-2" class="fa fa-caret-right"></span>&nbsp;Specific Programming Tasks
</a>
<ul id="topicSubGroup-0-2" class="nav-tertiary list-unstyled collapse">
<li><a class="" href="../../en-US/tasks/Tasks-Library_Design.html">Library Design</a></li>
<li><a class="" href="../../en-US/tasks/Tasks-Descriptors.html">File Descriptor Management</a></li>
<li><a class="" href="../../en-US/tasks/Tasks-File_System.html">File System Manipulation</a></li>
<li><a class="" href="../../en-US/tasks/Tasks-Temporary_Files.html">Temporary Files</a></li>
<li><a class="" href="../../en-US/tasks/Tasks-Processes.html">Processes</a></li>
<li><a class="" href="../../en-US/tasks/Tasks-Serialization.html">Serialization and Deserialization</a></li>
<li><a class="" href="../../en-US/tasks/Tasks-Cryptography.html">Cryptography</a></li>
<li><a class="" href="../../en-US/tasks/Tasks-Packaging.html">RPM Packaging</a></li>
</ul>
</li>
<li class="nav-header">
<a class="" href="#" data-toggle="collapse" data-target="#topicSubGroup-0-3">
<span id="sgSpan-0-3" class="fa fa-caret-down"></span>&nbsp;Implementing Security Features
</a>
<ul id="topicSubGroup-0-3" class="nav-tertiary list-unstyled collapse in">
<li><a class="" href="../../en-US/features/Features-Authentication.html">Authentication and Authorization</a></li>
<li><a class="" href="../../en-US/features/Features-TLS.html">Transport Layer Security (TLS)</a></li>
<li><a class=" active" href="../../en-US/features/Features-HSM.html">Hardware Security Modules and Smart Cards</a></li>
</ul>
</li>
<li><a class="" href="../../en-US/Revision_History.html">Revision History</a></li>
</ul>
</li>
</ul>
</div>
<div class="col-xs-12 col-sm-9 col-md-9 main">
<div class="page-header">
<h2>Hardware Security Modules and Smart Cards</h2>
</div>
<div id="preamble">
<div class="sectionbody">
<div class="paragraph">
<p>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.</p>
</div>
<div class="paragraph">
<p>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.</p>
</div>
<div class="paragraph">
<p>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 <code>opensc</code>
shared module (<code>opensc-pkcs11.so</code>) can be used for the majority
of smart cards available in the market. By convention these modules are located
at <code>/usr/lib64/pkcs11</code>. They can be used directly, or via
a higher level library.</p>
</div>
<div class="paragraph">
<p>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.</p>
</div>
<div class="ulist">
<ul>
<li>
<p>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 <a href="https://p11-glue.freedesktop.org/doc/p11-kit/pkcs11-conf.html">p11-kit
configuration files</a>, stored at <code>/etc/pkcs11/modules/</code>. For applications using
<code>engine_pkcs11</code> or GnuTLS the registered modules are
available without further configuration. Other applications will have to load
the <code>p11-kit-proxy.so</code> module.</p>
</li>
<li>
<p>Most crypto libraries support the <a href="https://tools.ietf.org/html/rfc7512">PKCS#11 URLs scheme</a>
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.</p>
</li>
<li>
<p>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.</p>
</li>
<li>
<p>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 <code>softhsm</code> which
provides a tool to setup a software HSM, and a PKCS#11 library.</p>
</li>
<li>
<p>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 <code>softhsm</code> 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.</p>
</li>
</ul>
</div>
</div>
</div>
<div class="sect1">
<h2 id="sect-Defensive_Coding-HSM-OpenSSL"><a class="anchor" href="#sect-Defensive_Coding-HSM-OpenSSL"></a>OpenSSL HSM Support</h2>
<div class="sectionbody">
<div class="paragraph">
<p>OpenSSL does not have native support for PKCS#11. It can
provide PKCS#11 support through the OpenSC&#8217;s project
<code>pkcs11</code> engine (formerly known as <code>engine_pkcs11</code>).
As such software intended to use HSMs, must utilize that engine.</p>
</div>
<div class="paragraph">
<p>Engine <code>pkcs11</code> 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 <code>p11-kit-proxy.so</code>.</p>
</div>
<div class="paragraph">
<p>The following example demonstrates the initialization of the pkcs11 engine
and its usage to sign data.</p>
</div>
<div id="ex-Defensive_Coding-HSM-OpenSSL" class="exampleblock">
<div class="title">Example 1. Signing data with HSM and OpenSSL</div>
<div class="content">
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code data-lang="c">OpenSSL_add_all_algorithms();
ERR_load_crypto_strings();
ERR_clear_error();
ENGINE_load_builtin_engines();
e = ENGINE_by_id(<span style="background-color:hsla(0,100%,50%,0.05)"><span style="color:#710">&quot;</span><span style="color:#D20">pkcs11</span><span style="color:#710">&quot;</span></span>);
<span style="color:#080;font-weight:bold">if</span> (!e) {
display_openssl_errors(__LINE__);
exit(<span style="color:#00D">1</span>);
}
<span style="color:#080;font-weight:bold">if</span> (module_path) {
fprintf(stderr, <span style="background-color:hsla(0,100%,50%,0.05)"><span style="color:#710">&quot;</span><span style="color:#D20">loading: %s</span><span style="color:#b0b">\n</span><span style="color:#710">&quot;</span></span>, module_path);
<span style="color:#080;font-weight:bold">if</span> (!ENGINE_ctrl_cmd_string(e, <span style="background-color:hsla(0,100%,50%,0.05)"><span style="color:#710">&quot;</span><span style="color:#D20">MODULE_PATH</span><span style="color:#710">&quot;</span></span>, module_path, <span style="color:#00D">0</span>)) {
display_openssl_errors(__LINE__);
exit(<span style="color:#00D">1</span>);
}
}
<span style="color:#080;font-weight:bold">if</span> (!ENGINE_init(e)) {
display_openssl_errors(__LINE__);
exit(<span style="color:#00D">1</span>);
}
<span style="color:#080;font-weight:bold">if</span> (key_pass &amp;&amp; !ENGINE_ctrl_cmd_string(e, <span style="background-color:hsla(0,100%,50%,0.05)"><span style="color:#710">&quot;</span><span style="color:#D20">PIN</span><span style="color:#710">&quot;</span></span>, key_pass, <span style="color:#00D">0</span>)) {
display_openssl_errors(__LINE__);
exit(<span style="color:#00D">1</span>);
}
private_key = ENGINE_load_private_key(e, private_key_name, <span style="color:#069">NULL</span>, <span style="color:#069">NULL</span>);
<span style="color:#080;font-weight:bold">if</span> (!private_key) {
fprintf(stderr, <span style="background-color:hsla(0,100%,50%,0.05)"><span style="color:#710">&quot;</span><span style="color:#D20">cannot load: %s</span><span style="color:#b0b">\n</span><span style="color:#710">&quot;</span></span>, private_key_name);
display_openssl_errors(__LINE__);
exit(<span style="color:#00D">1</span>);
}
display_openssl_errors(__LINE__);
digest_algo = EVP_get_digestbyname(<span style="background-color:hsla(0,100%,50%,0.05)"><span style="color:#710">&quot;</span><span style="color:#D20">sha256</span><span style="color:#710">&quot;</span></span>);
EVP_MD_CTX_init(&amp;ctx);
<span style="color:#080;font-weight:bold">if</span> (EVP_DigestInit(&amp;ctx, digest_algo) &lt;= <span style="color:#00D">0</span>) {
display_openssl_errors(__LINE__);
exit(<span style="color:#00D">1</span>);
}
EVP_SignInit(&amp;ctx, digest_algo);
<span style="color:#579">#define</span> TEST_DATA <span style="background-color:hsla(0,100%,50%,0.05)"><span style="color:#710">&quot;</span><span style="color:#D20">test data</span><span style="color:#710">&quot;</span></span>
<span style="color:#080;font-weight:bold">if</span> (EVP_SignUpdate(&amp;ctx, TEST_DATA, <span style="color:#080;font-weight:bold">sizeof</span>(TEST_DATA) - <span style="color:#00D">1</span>) &lt;= <span style="color:#00D">0</span>) {
display_openssl_errors(__LINE__);
exit(<span style="color:#00D">1</span>);
}
n = <span style="color:#080;font-weight:bold">sizeof</span>(buf);
<span style="color:#080;font-weight:bold">if</span> (EVP_SignFinal(&amp;ctx, buf, &amp;n, private_key) &lt;= <span style="color:#00D">0</span>) {
display_openssl_errors(__LINE__);
exit(<span style="color:#00D">1</span>);
}
EVP_PKEY_free(private_key);
ENGINE_finish(e);</code></pre>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="sect-Defensive_Coding-HSM-GNUTLS"><a class="anchor" href="#sect-Defensive_Coding-HSM-GNUTLS"></a>GnuTLS HSM Support</h2>
<div class="sectionbody">
<div class="paragraph">
<p>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.</p>
</div>
<div class="paragraph">
<p>The following example demonstrates the initialization of the pkcs11 engine
and its usage to sign data.</p>
</div>
<div id="ex-Defensive_Coding-HSM-GNUTLS" class="exampleblock">
<div class="title">Example 2. Signing data with HSM and GnuTLS</div>
<div class="content">
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code data-lang="c"><span style="color:#080;font-weight:bold">if</span> (module_path) {
ret = gnutls_pkcs11_init(GNUTLS_PKCS11_FLAG_MANUAL, <span style="color:#069">NULL</span>);
<span style="color:#080;font-weight:bold">if</span> (ret &lt; <span style="color:#00D">0</span>) {
fprintf(stderr, <span style="background-color:hsla(0,100%,50%,0.05)"><span style="color:#710">&quot;</span><span style="color:#D20">error in %d: %s</span><span style="color:#b0b">\n</span><span style="color:#710">&quot;</span></span>, __LINE__, gnutls_strerror(ret));
exit(<span style="color:#00D">1</span>);
}
ret = gnutls_pkcs11_add_provider(module_path, <span style="color:#069">NULL</span>);
<span style="color:#080;font-weight:bold">if</span> (ret &lt; <span style="color:#00D">0</span>) {
fprintf(stderr, <span style="background-color:hsla(0,100%,50%,0.05)"><span style="color:#710">&quot;</span><span style="color:#D20">error in %d: %s</span><span style="color:#b0b">\n</span><span style="color:#710">&quot;</span></span>, __LINE__, gnutls_strerror(ret));
exit(<span style="color:#00D">1</span>);
}
}
<span style="color:#080;font-weight:bold">if</span> (key_pass)
gnutls_pkcs11_set_pin_function(pin_function, key_pass);
ret = gnutls_privkey_init(&amp;private_key);
<span style="color:#080;font-weight:bold">if</span> (ret &lt; <span style="color:#00D">0</span>) {
fprintf(stderr, <span style="background-color:hsla(0,100%,50%,0.05)"><span style="color:#710">&quot;</span><span style="color:#D20">error in %d: %s</span><span style="color:#b0b">\n</span><span style="color:#710">&quot;</span></span>, __LINE__, gnutls_strerror(ret));
exit(<span style="color:#00D">1</span>);
}
ret = gnutls_privkey_import_url(private_key, private_key_name, <span style="color:#00D">0</span>);
<span style="color:#080;font-weight:bold">if</span> (ret &lt; <span style="color:#00D">0</span>) {
fprintf(stderr, <span style="background-color:hsla(0,100%,50%,0.05)"><span style="color:#710">&quot;</span><span style="color:#D20">error in %d: %s</span><span style="color:#b0b">\n</span><span style="color:#710">&quot;</span></span>, __LINE__, gnutls_strerror(ret));
exit(<span style="color:#00D">1</span>);
}
ret = gnutls_privkey_sign_data(private_key, GNUTLS_DIG_SHA256, <span style="color:#00D">0</span>,
&amp;testdata, &amp;signature);
<span style="color:#080;font-weight:bold">if</span> (ret &lt; <span style="color:#00D">0</span>) {
fprintf(stderr, <span style="background-color:hsla(0,100%,50%,0.05)"><span style="color:#710">&quot;</span><span style="color:#D20">error in %d: %s</span><span style="color:#b0b">\n</span><span style="color:#710">&quot;</span></span>, __LINE__, gnutls_strerror(ret));
exit(<span style="color:#00D">1</span>);
}
gnutls_privkey_deinit(private_key);
gnutls_free(signature.data);</code></pre>
</div>
</div>
</div>
</div>
<div class="paragraph">
<p>The PIN callback function can be either set globally as in
the example above or locally by utilizing functions such as <code>gnutls_privkey_set_pin_function</code>.
An example PIN callback function is shown below.</p>
</div>
<div id="ex-Defensive_Coding-HSM-GNUTLS-PIN" class="exampleblock">
<div class="title">Example 3. An example PIN callback with GNUTLS</div>
<div class="content">
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code data-lang="c"><span style="color:#0a8;font-weight:bold">int</span> pin_function(<span style="color:#088;font-weight:bold">void</span> *userdata, <span style="color:#0a8;font-weight:bold">int</span> attempt, <span style="color:#088;font-weight:bold">const</span> <span style="color:#0a8;font-weight:bold">char</span> *token_url,
<span style="color:#088;font-weight:bold">const</span> <span style="color:#0a8;font-weight:bold">char</span> *token_label, <span style="color:#0a8;font-weight:bold">unsigned</span> flags, <span style="color:#0a8;font-weight:bold">char</span> *pin, size_t pin_max)
{
<span style="color:#080;font-weight:bold">if</span> (flags &amp; GNUTLS_PIN_FINAL_TRY)
printf(<span style="background-color:hsla(0,100%,50%,0.05)"><span style="color:#710">&quot;</span><span style="color:#D20">This is the final try before locking!</span><span style="color:#b0b">\n</span><span style="color:#710">&quot;</span></span>);
<span style="color:#080;font-weight:bold">if</span> (flags &amp; GNUTLS_PIN_COUNT_LOW)
printf(<span style="background-color:hsla(0,100%,50%,0.05)"><span style="color:#710">&quot;</span><span style="color:#D20">Only few tries left before locking!</span><span style="color:#b0b">\n</span><span style="color:#710">&quot;</span></span>);
<span style="color:#080;font-weight:bold">if</span> (flags &amp; GNUTLS_PIN_WRONG)
printf(<span style="background-color:hsla(0,100%,50%,0.05)"><span style="color:#710">&quot;</span><span style="color:#D20">Wrong PIN has been provided in the previous attempt</span><span style="color:#b0b">\n</span><span style="color:#710">&quot;</span></span>);
<span style="color:#777">/* userdata is the second value passed to gnutls_pkcs11_set_pin_function()
* in this example we passed the PIN as a null terminated value.
*/</span>
snprintf(pin, pin_max, <span style="background-color:hsla(0,100%,50%,0.05)"><span style="color:#710">&quot;</span><span style="color:#D20">%s</span><span style="color:#710">&quot;</span></span>, (<span style="color:#0a8;font-weight:bold">char</span>*)userdata);
<span style="color:#080;font-weight:bold">return</span> <span style="color:#00D">0</span>;
}</code></pre>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="sect-Defensive_Coding-HSM-NSS"><a class="anchor" href="#sect-Defensive_Coding-HSM-NSS"></a>NSS HSM Support</h2>
<div class="sectionbody">
<div class="paragraph">
<p>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.</p>
</div>
<div class="paragraph">
<p>The following example demonstrates a typical NSS application for signing.</p>
</div>
<div id="ex-Defensive_Coding-HSM-NSS" class="exampleblock">
<div class="title">Example 4. Signing data with HSM and NSS</div>
<div class="content">
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code data-lang="c">SECStatus rv;
CERTCertificate *cert = <span style="color:#069">NULL</span>;
SECKEYPrivateKey *pvtkey = <span style="color:#069">NULL</span>;
SECItem signature = { siBuffer, <span style="color:#069">NULL</span>, <span style="color:#00D">0</span> };
SECOidTag algTag;
<span style="color:#0a8;font-weight:bold">int</span> r = <span style="color:#00D">1</span>;
<span style="color:#0a8;font-weight:bold">unsigned</span> <span style="color:#0a8;font-weight:bold">char</span> buf[] = <span style="background-color:hsla(0,100%,50%,0.05)"><span style="color:#710">&quot;</span><span style="color:#D20">test data to sign</span><span style="color:#710">&quot;</span></span>;
<span style="color:#088;font-weight:bold">const</span> <span style="color:#0a8;font-weight:bold">char</span> *cert_name;
<span style="color:#0a8;font-weight:bold">unsigned</span> i;
<span style="color:#080;font-weight:bold">if</span> (argc &lt; <span style="color:#00D">3</span>) {
fprintf(stderr, <span style="background-color:hsla(0,100%,50%,0.05)"><span style="color:#710">&quot;</span><span style="color:#D20">usage: %s [cert name] [PIN]</span><span style="color:#b0b">\n</span><span style="color:#b0b">\n</span><span style="color:#710">&quot;</span></span>, argv[<span style="color:#00D">0</span>]);
exit(<span style="color:#00D">1</span>);
}
cert_name = argv[<span style="color:#00D">1</span>];
pin = argv[<span style="color:#00D">2</span>];
PK11_SetPasswordFunc(passwdcb);
NSS_InitializePRErrorTable();
rv = NSS_Init(<span style="background-color:hsla(0,100%,50%,0.05)"><span style="color:#710">&quot;</span><span style="color:#D20">.</span><span style="color:#710">&quot;</span></span>);
<span style="color:#080;font-weight:bold">if</span> (rv != SECSuccess) {
fprintf(stderr, <span style="background-color:hsla(0,100%,50%,0.05)"><span style="color:#710">&quot;</span><span style="color:#D20">NSS initialization failed (err %d)</span><span style="color:#b0b">\n</span><span style="color:#710">&quot;</span></span>, PR_GetError());
<span style="color:#080;font-weight:bold">goto</span> cleanup;
}
cert = PK11_FindCertFromNickname(cert_name, <span style="color:#069">NULL</span>);
<span style="color:#080;font-weight:bold">if</span> (cert == <span style="color:#069">NULL</span>) {
fprintf(stderr, <span style="background-color:hsla(0,100%,50%,0.05)"><span style="color:#710">&quot;</span><span style="color:#D20">Couldn't find cert %s in NSS db (err %d: %s)</span><span style="color:#b0b">\n</span><span style="color:#710">&quot;</span></span>,
cert_name, PR_GetError(), PORT_ErrorToString(PR_GetError()));
<span style="color:#080;font-weight:bold">goto</span> cleanup;
}
fprintf(stderr, <span style="background-color:hsla(0,100%,50%,0.05)"><span style="color:#710">&quot;</span><span style="color:#D20">Buffer being signed = </span><span style="color:#b0b">\n</span><span style="color:#D20">%s</span><span style="color:#b0b">\n</span><span style="color:#710">&quot;</span></span>, buf);
pvtkey = PK11_FindKeyByAnyCert(cert, <span style="color:#069">NULL</span>);
<span style="color:#080;font-weight:bold">if</span> (pvtkey == <span style="color:#069">NULL</span>) {
fprintf(stderr, <span style="background-color:hsla(0,100%,50%,0.05)"><span style="color:#710">&quot;</span><span style="color:#D20">Couldn't find private key for cert %s (err %d: %s)</span><span style="color:#b0b">\n</span><span style="color:#710">&quot;</span></span>,
cert_name, PR_GetError(), PORT_ErrorToString(PR_GetError()));
<span style="color:#080;font-weight:bold">goto</span> cleanup;
}
<span style="color:#777">/* get the algtag. Pick the default hash algorithm */</span>
algTag = SEC_GetSignatureAlgorithmOidTag(pvtkey-&gt;keyType, SEC_OID_UNKNOWN);
fprintf(stderr, <span style="background-color:hsla(0,100%,50%,0.05)"><span style="color:#710">&quot;</span><span style="color:#D20">Signing with alg = %s (%d)</span><span style="color:#b0b">\n</span><span style="color:#710">&quot;</span></span>,
SECOID_FindOIDTagDescription(algTag), algTag);
rv = SEC_SignData(&amp;signature, buf, <span style="color:#080;font-weight:bold">sizeof</span>(buf)-<span style="color:#00D">1</span>, pvtkey, algTag);
<span style="color:#080;font-weight:bold">if</span> (rv != SECSuccess) {
fprintf(stderr, <span style="background-color:hsla(0,100%,50%,0.05)"><span style="color:#710">&quot;</span><span style="color:#D20">sign with Private Key failed (err %d: %s)</span><span style="color:#b0b">\n</span><span style="color:#710">&quot;</span></span>,
PR_GetError(), PORT_ErrorToString(PR_GetError()));
<span style="color:#080;font-weight:bold">goto</span> cleanup;
}</code></pre>
</div>
</div>
</div>
</div>
<div class="paragraph">
<p>To use the example above with an HSM or smart card you will need to do the following.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code data-lang="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 &quot;My HSM&quot; -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 &quot;${token_name}:${cert_name}&quot;</code></pre>
</div>
</div>
<div id="ex-Defensive_Coding-HSM-NSS-PIN" class="exampleblock">
<div class="title">Example 5. An example PIN callback with NSS</div>
<div class="content">
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code data-lang="c"><span style="color:#0a8;font-weight:bold">char</span> *passwdcb(PK11SlotInfo * slot, PRBool retry, <span style="color:#088;font-weight:bold">void</span> *arg)
{
<span style="color:#080;font-weight:bold">if</span> (!isatty(STDIN_FILENO) &amp;&amp; retry) {
<span style="color:#777">/* 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. */</span>
<span style="color:#080;font-weight:bold">return</span> <span style="color:#069">NULL</span>;
}
<span style="color:#080;font-weight:bold">if</span> (retry) {
printf(<span style="background-color:hsla(0,100%,50%,0.05)"><span style="color:#710">&quot;</span><span style="color:#D20">Warning: Wrong PIN has been provided in the previous attempt</span><span style="color:#b0b">\n</span><span style="color:#710">&quot;</span></span>);
<span style="color:#080;font-weight:bold">if</span> (PK11_IsHW(slot)) {
printf
(<span style="background-color:hsla(0,100%,50%,0.05)"><span style="color:#710">&quot;</span><span style="color:#D20"> NOTE: multiple pin failures could result in locking your device</span><span style="color:#b0b">\n</span><span style="color:#710">&quot;</span></span>);
}
}
<span style="color:#080;font-weight:bold">if</span> (pin == <span style="color:#069">NULL</span>)
<span style="color:#080;font-weight:bold">return</span> pin;
<span style="color:#080;font-weight:bold">else</span>
<span style="color:#080;font-weight:bold">return</span> strdup(pin);
}</code></pre>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<div id="bottom" class="text-muted py-3" >
<div class="foot">
<div class="container">
<div class="row footerlinks">
<div class="col-sm-3 col-xs-6 widget">
<h3 class="widget-title">About</h3>
<div class="widget-body">
<dl>
<dd><a href="https://fedoraproject.org/wiki/Overview">About Fedora</a></dd>
<dd><a href="https://getfedora.org/en/sponsors">Sponsors</a></dd>
<dd><a href="https://fedoramagazine.org">Fedora Magazine</a></dd>
<dd><a href="https://fedoraproject.org/wiki/Legal:Main#Legal">Legal</a></dd>
</dl>
<ul class="list-inline">
<li>
<a href="https://www.facebook.com/TheFedoraProject" class="btn-social btn-outline"><i class="fa fa-fw fa-facebook"></i></a>
</li>
<li>
<a href="https://plus.google.com/112917221531140868607" class="btn-social btn-outline"><i class="fa fa-fw fa-google-plus"></i></a>
</li>
<li>
<a href="https://twitter.com/fedora" class="btn-social btn-outline"><i class="fa fa-fw fa-twitter"></i></a>
</li>
</ul>
</div>
</div>
<div class="col-sm-3 col-xs-6 widget">
<h3 class="widget-title uppercase">Download</h3>
<div class="widget-body">
<dl>
<dd><a href="https://getfedora.org/en/workstation/download">Get Fedora Workstation</a></dd>
<dd><a href="https://getfedora.org/en/server/download">Get Fedora Server</a></dd>
<dd><a href="https://getfedora.org/en/atomic/download">Get Fedora Atomic</a></dd>
<dd><a href="https://spins.fedoraproject.org">Fedora Spins</a></dd>
<dd><a href="https://labs.fedoraproject.org">Fedora Labs</a></dd>
<dd><a href="https://arm.fedoraproject.org">Fedora ARM<span class="sup">&reg;</span></a></dd>
<dd><a href="https://alt.fedoraproject.org/">Alternative Downloads</a></dd>
</dl>
</div>
</div>
<div class="col-sm-3 col-xs-6 widget">
<h3 class="widget-title">Support</h3>
<div class="widget-body">
<dl>
<dd><a href="https://fedoraproject.org/wiki/Communicating_and_getting_help">Get Help</a></dd>
<dd><a href="https://ask.fedoraproject.org/">Ask Fedora</a></dd>
<dd><a href="https://fedoraproject.org/wiki/Common_F27_bugs">Common Bugs</a></dd>
<dd><a href="https://developer.fedoraproject.org/">Fedora Developer Portal</a></dd>
<dd><a href="https://docs.fedoraproject.org/f27/install-guide/index.html">Installation Guide</a></dd>
</dl>
</div>
</div>
<div class="col-sm-3 col-xs-6 widget">
<h3 class="widget-title">Join</h3>
<div class="widget-body">
<dl>
<dd><a href="https://fedoraproject.org/wiki/Join">Join Fedora</a></dd>
<dd><a href="http://fedoraplanet.org">Planet Fedora</a></dd>
<dd><a href="https://fedoraproject.org/wiki/SIGs">Fedora SIGs</a></dd>
<dd><a href="https://admin.fedoraproject.org/accounts/">Fedora Account System</a></dd>
<dd><a href="https://fedoracommunity.org/">Fedora Community</a></dd>
</dl>
</div>
</div>
</div> <!-- /row of widgets -->
<div class="row">
<div class="col-md-2">
<div class="widget-body">
<a href="https://www.redhat.com/"><img class="rh-logo" src="../../../master/_images/redhat-logo.png" alt="Red Hat Logo" /></a>
</div>
</div>
<div class="col-md-7">
<div class="widget-body">
<p class="sponsor">Fedora is sponsored by Red Hat.</p>
<p class="sponsor"><a href="https://www.redhat.com/en/technologies/linux-platforms/articles/relationship-between-fedora-and-rhel">Learn more about the relationship between Red Hat and Fedora &raquo;</a></p>
<p class="copy">&copy; 2017 Red Hat, Inc. and others. Please send any comments or corrections to the <a href="https://pagure.io/fedora-docs/docs-fp-o">documentation team</a></p>
</div>
</div>
</div> <!-- /row of widgets -->
</div>
</div>
</div>
<!-- jQuery (necessary for Bootstrap's JavaScript plugins) -->
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>
<!-- Latest compiled and minified JavaScript -->
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/js/bootstrap.min.js"></script>
<script src="../../../master/_javascripts/bootstrap-offcanvas.js" type="text/javascript"></script>
<script type="text/javascript">
/*<![CDATA[*/
$(document).ready(function() {
$("[id^='topicGroup']").on('show.bs.collapse', function (event) {
if (!($(event.target).attr('id').match(/^topicSubGroup/))) {
$(this).parent().find("[id^='tgSpan']").toggleClass("fa-angle-right fa-angle-down");
}
});
$("[id^='topicGroup']").on('hide.bs.collapse', function (event) {
if (!($(event.target).attr('id').match(/^topicSubGroup/))) {
$(this).parent().find("[id^='tgSpan']").toggleClass("fa-angle-right fa-angle-down");
}
});
$("[id^='topicSubGroup']").on('show.bs.collapse', function () {
$(this).parent().find("[id^='sgSpan']").toggleClass("fa-caret-right fa-caret-down");
});
$("[id^='topicSubGroup']").on('hide.bs.collapse', function () {
$(this).parent().find("[id^='sgSpan']").toggleClass("fa-caret-right fa-caret-down");
});
});
/*]]>*/
</script>
</body>
</html>

File diff suppressed because it is too large Load diff

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load diff

View file

@ -1,641 +0,0 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta content="IE=edge" http-equiv="X-UA-Compatible">
<meta content="width=device-width, initial-scale=1.0" name="viewport">
<title>Defensive Coding Guide | Defensive Coding Guide | Programming Languages | The C++ Programming&nbsp;Language</title>
<!-- Bootstrap -->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css">
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap-theme.min.css">
<!-- Overpass Font -->
<link rel="stylesheet" href="https://overpass-30e2.kxcdn.com/overpass.css">
<link href="../../../master/_stylesheets/asciibinder.css" rel="stylesheet" />
<!-- HTML5 shim and Respond.js for IE8 support of HTML5 elements and media queries -->
<!-- WARNING: Respond.js doesn't work if you view the page via file:// -->
<!--[if lt IE 9]>
<script src="https://oss.maxcdn.com/html5shiv/3.7.2/html5shiv.min.js"></script>
<script src="https://oss.maxcdn.com/respond/1.4.2/respond.min.js"></script>
<![endif]-->
<link href="../../../master/_images/favicon32x32.png" rel="shortcut icon" type="text/css">
<!--[if IE]><link rel="shortcut icon" href="../../../master/_images/favicon.ico"><![endif]-->
<meta content="AsciiBinder" name="application-name">
</head>
<body>
<div class="navbar navbar-default" role="navigation">
<div class="container-fluid">
<div class="navbar-header">
<a class="navbar-brand" href="https://docs.fedoraproject.org/"><img alt="Fedora Documentation" src="../../../master/_images/fedora.svg"></a>
</div>
</div>
</div>
<div class="container">
<p class="toggle-nav visible-xs pull-left">
<button class="btn btn-default btn-sm" type="button" data-toggle="offcanvas">Toggle nav</button>
</p>
<ol class="breadcrumb">
<li class="sitename">
<a href="../../../index.html">Home</a>
</li>
<li class="hidden-xs active">
<a href="../../en-US/index.html">Defensive Coding Guide </a>
</li>
<li class="hidden-xs active">
<a href="../../en-US/index.html">Defensive Coding Guide</a>
</li>
<li class="hidden-xs active"><a href="../../en-US/programming-languages/C.html">Programming Languages</a></li>
<li class="hidden-xs active">
The C++ Programming&nbsp;Language
</li>
</ol>
<div class="row row-offcanvas row-offcanvas-left">
<div class="col-xs-8 col-sm-3 col-md-3 sidebar sidebar-offcanvas">
<ul class="nav nav-sidebar">
<li class="nav-header">
<a class="" href="#" data-toggle="collapse" data-target="#topicGroup0">
<span id="tgSpan0" class="fa fa-angle-down"></span>Defensive Coding Guide
</a>
<ul id="topicGroup0" class="collapse in list-unstyled">
<li><a class="" href="../../en-US/index.html">Book Information</a></li>
<li class="nav-header">
<a class="" href="#" data-toggle="collapse" data-target="#topicSubGroup-0-1">
<span id="sgSpan-0-1" class="fa fa-caret-down"></span>&nbsp;Programming Languages
</a>
<ul id="topicSubGroup-0-1" class="nav-tertiary list-unstyled collapse in">
<li><a class="" href="../../en-US/programming-languages/C.html">The C Programming Language</a></li>
<li><a class=" active" href="../../en-US/programming-languages/CXX.html">The C++ Programming&nbsp;Language</a></li>
<li><a class="" href="../../en-US/programming-languages/Java.html">The Java Programming Language</a></li>
<li><a class="" href="../../en-US/programming-languages/Python.html">The Python Programming Language</a></li>
<li><a class="" href="../../en-US/programming-languages/Shell.html">Shell Programming and bash</a></li>
<li><a class="" href="../../en-US/programming-languages/Go.html">The Go Programming Language</a></li>
<li><a class="" href="../../en-US/programming-languages/Vala.html">The Vala Programming Language</a></li>
</ul>
</li>
<li class="nav-header">
<a class="" href="#" data-toggle="collapse" data-target="#topicSubGroup-0-2">
<span id="sgSpan-0-2" class="fa fa-caret-right"></span>&nbsp;Specific Programming Tasks
</a>
<ul id="topicSubGroup-0-2" class="nav-tertiary list-unstyled collapse">
<li><a class="" href="../../en-US/tasks/Tasks-Library_Design.html">Library Design</a></li>
<li><a class="" href="../../en-US/tasks/Tasks-Descriptors.html">File Descriptor Management</a></li>
<li><a class="" href="../../en-US/tasks/Tasks-File_System.html">File System Manipulation</a></li>
<li><a class="" href="../../en-US/tasks/Tasks-Temporary_Files.html">Temporary Files</a></li>
<li><a class="" href="../../en-US/tasks/Tasks-Processes.html">Processes</a></li>
<li><a class="" href="../../en-US/tasks/Tasks-Serialization.html">Serialization and Deserialization</a></li>
<li><a class="" href="../../en-US/tasks/Tasks-Cryptography.html">Cryptography</a></li>
<li><a class="" href="../../en-US/tasks/Tasks-Packaging.html">RPM Packaging</a></li>
</ul>
</li>
<li class="nav-header">
<a class="" href="#" data-toggle="collapse" data-target="#topicSubGroup-0-3">
<span id="sgSpan-0-3" class="fa fa-caret-right"></span>&nbsp;Implementing Security Features
</a>
<ul id="topicSubGroup-0-3" class="nav-tertiary list-unstyled collapse">
<li><a class="" href="../../en-US/features/Features-Authentication.html">Authentication and Authorization</a></li>
<li><a class="" href="../../en-US/features/Features-TLS.html">Transport Layer Security (TLS)</a></li>
<li><a class="" href="../../en-US/features/Features-HSM.html">Hardware Security Modules and Smart Cards</a></li>
</ul>
</li>
<li><a class="" href="../../en-US/Revision_History.html">Revision History</a></li>
</ul>
</li>
</ul>
</div>
<div class="col-xs-12 col-sm-9 col-md-9 main">
<div class="page-header">
<h2>The C++ Programming Language</h2>
</div>
<div class="sect1">
<h2 id="sect-Defensive_Coding-CXX-Language"><a class="anchor" href="#sect-Defensive_Coding-CXX-Language"></a>The Core Language</h2>
<div class="sectionbody">
<div class="paragraph">
<p>C++ includes a large subset of the C language. As far as the C
subset is used, the recommendations in <a href="#chap-Defensive_Coding-C">[chap-Defensive_Coding-C]</a> apply.</p>
</div>
<div class="sect2">
<h3 id="array-allocation-with-code-operator-new-code"><a class="anchor" href="#array-allocation-with-code-operator-new-code"></a>Array Allocation with <code>operator new[]</code></h3>
<div class="paragraph">
<p>For very large values of <code>n</code>, an expression
like <code>new T[n]</code> 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 <code>sizeof(T) * size_t(n)<br>
cookie_size</code>, where <code>cookie_size</code> 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.)</p>
</div>
<div class="paragraph">
<p>The <code>std::vector</code> template can be used instead
an explicit array allocation. (The GCC implementation detects
overflow internally.)</p>
</div>
<div class="paragraph">
<p>If there is no alternative to <code>operator new[]</code>
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 <code>new T[n]</code> example,
the size check could be <code>n || (n &gt; 0 &amp;&amp; n &gt;
(size_t(-1) - 8) / sizeof(T))</code>. (See <a href="#sect-Defensive_Coding-C-Arithmetic">[sect-Defensive_Coding-C-Arithmetic]</a>.) If there are
additional dimensions (which must be constants according to the
C++ standard), these should be included as factors in the
divisor.</p>
</div>
<div class="paragraph">
<p>These countermeasures prevent out-of-bounds writes and potential
code execution. Very large memory allocations can still lead to
a denial of service. <a href="#sect-Defensive_Coding-Tasks-Serialization-Decoders">[sect-Defensive_Coding-Tasks-Serialization-Decoders]</a>
contains suggestions for mitigating this problem when processing
untrusted data.</p>
</div>
<div class="paragraph">
<p>See <a href="#sect-Defensive_Coding-C-Allocators-Arrays">[sect-Defensive_Coding-C-Allocators-Arrays]</a>
for array allocation advice for C-style memory allocation.</p>
</div>
</div>
<div class="sect2">
<h3 id="overloading"><a class="anchor" href="#overloading"></a>Overloading</h3>
<div class="paragraph">
<p>Do not overload functions with versions that have different
security characteristics. For instance, do not implement a
function <code>strcat</code> which works on
<code>std::string</code> arguments. Similarly, do not name
methods after such functions.</p>
</div>
</div>
<div class="sect2">
<h3 id="abi-compatibility-and-preparing-for-security-updates"><a class="anchor" href="#abi-compatibility-and-preparing-for-security-updates"></a>ABI compatibility and preparing for security updates</h3>
<div class="paragraph">
<p>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.</p>
</div>
<div class="paragraph">
<p>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:</p>
</div>
<div class="ulist">
<ul>
<li>
<p>Avoid inline functions.</p>
</li>
<li>
<p>Use the pointer-to-implementation idiom.</p>
</li>
<li>
<p>Try to avoid templates. Use them if the increased type
safety provides a benefit to the programmer.</p>
</li>
<li>
<p>Move security-critical code out of templated code, so that
it can be patched in a central place if necessary.</p>
</li>
</ul>
</div>
<div class="paragraph">
<p>The KDE project publishes a document with more extensive
guidelines on ABI-preserving changes to C++ code, <a href="https://community.kde.org/Policies/Binary_Compatibility_Issues_With_C%2B%2B">Policies/Binary
Compatibility Issues With C++</a>
(<strong>d-pointer</strong> refers to the
pointer-to-implementation idiom).</p>
</div>
</div>
<div class="sect2">
<h3 id="sect-Defensive_Coding-CXX-Language-CXX11"><a class="anchor" href="#sect-Defensive_Coding-CXX-Language-CXX11"></a>C++0X and C++11 Support</h3>
<div class="paragraph">
<p>GCC offers different language compatibility modes:</p>
</div>
<div class="ulist">
<ul>
<li>
<p><code class="option">-std=c++98</code> for the original 1998 C++
standard</p>
</li>
<li>
<p><code class="option">-std=c++03</code> for the 1998 standard with the
changes from the TR1 technical report</p>
</li>
<li>
<p><code class="option">-std=c++11</code> for the 2011 C++ standard. This
option should not be used.</p>
</li>
<li>
<p><code class="option">-std=c++0x</code> for several different versions
of C++11 support in development, depending on the GCC
version. This option should not be used.</p>
</li>
</ul>
</div>
<div class="paragraph">
<p>For each of these flags, there are variants which also enable
GNU extensions (mostly language features also found in C99 or
C11):</p>
</div>
<div class="ulist">
<ul>
<li>
<p><code class="option">-std=gnu++98</code></p>
</li>
<li>
<p><code class="option">-std=gnu++03</code></p>
</li>
<li>
<p><code class="option">-std=gnu++11</code></p>
</li>
</ul>
</div>
<div class="paragraph">
<p>Again, <code class="option">-std=gnu++11</code> should not be used.</p>
</div>
<div class="paragraph">
<p>If you enable C++11 support, the ABI of the standard C++ library
<code>libstdc++</code> 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).</p>
</div>
<div class="paragraph">
<p>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.</p>
</div>
<div class="paragraph">
<p>Some C++11 features (or approximations thereof) are available
with TR1 support, that is, with <code class="option">-std=c03` or
[option]`-std=gnu03</code> and in the
<code>&lt;tr1/*&gt;</code> header files. This includes
<code>std::tr1::shared_ptr</code> (from
<code>&lt;tr1/memory&gt;</code>) and
<code>std::tr1::function</code> (from
<code>&lt;tr1/functional&gt;</code>). For other C++11
features, the Boost C++ library contains replacements.</p>
</div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="sect-Defensive_Coding-CXX-Std"><a class="anchor" href="#sect-Defensive_Coding-CXX-Std"></a>The C++ Standard Library</h2>
<div class="sectionbody">
<div class="paragraph">
<p>The C++ standard library includes most of its C counterpart
by reference, see <a href="#sect-Defensive_Coding-C-Libc">[sect-Defensive_Coding-C-Libc]</a>.</p>
</div>
<div class="sect2">
<h3 id="sect-Defensive_Coding-CXX-Std-Functions"><a class="anchor" href="#sect-Defensive_Coding-CXX-Std-Functions"></a>Functions That Are Difficult to Use</h3>
<div class="paragraph">
<p>This section collects functions and function templates which are
part of the standard library and are difficult to use.</p>
</div>
<div class="sect3">
<h4 id="sect-Defensive_Coding-CXX-Std-Functions-Unpaired_Iterators"><a class="anchor" href="#sect-Defensive_Coding-CXX-Std-Functions-Unpaired_Iterators"></a>Unpaired Iterators</h4>
<div class="paragraph">
<p>Functions which use output operators or iterators which do not
come in pairs (denoting ranges) cannot perform iterator range
checking.
(See <a href="#sect-Defensive_Coding-CXX-Std-Iterators">Iterators</a>)
Function templates which involve output iterators are
particularly dangerous:</p>
</div>
<div class="ulist">
<ul>
<li>
<p><code>std::copy</code></p>
</li>
<li>
<p><code>std::copy_backward</code></p>
</li>
<li>
<p><code>std::copy_if</code></p>
</li>
<li>
<p><code>std::move</code> (three-argument variant)</p>
</li>
<li>
<p><code>std::move_backward</code></p>
</li>
<li>
<p><code>std::partition_copy_if</code></p>
</li>
<li>
<p><code>std::remove_copy</code></p>
</li>
<li>
<p><code>std::remove_copy_if</code></p>
</li>
<li>
<p><code>std::replace_copy</code></p>
</li>
<li>
<p><code>std::replace_copy_if</code></p>
</li>
<li>
<p><code>std::swap_ranges</code></p>
</li>
<li>
<p><code>std::transform</code></p>
</li>
</ul>
</div>
<div class="paragraph">
<p>In addition, <code>std::copy_n</code>,
<code>std::fill_n</code> and
<code>std::generate_n</code> 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.</p>
</div>
<div class="paragraph">
<p>These output-iterator-expecting functions should only be used
with unlimited-range output iterators, such as iterators
obtained with the <code>std::back_inserter</code>
function.</p>
</div>
<div class="paragraph">
<p>Other functions use single input or forward iterators, which can
read beyond the end of the input range if the caller is not careful:</p>
</div>
<div class="ulist">
<ul>
<li>
<p><code>std::equal</code></p>
</li>
<li>
<p><code>std::is_permutation</code></p>
</li>
<li>
<p><code>std::mismatch</code></p>
</li>
</ul>
</div>
</div>
</div>
<div class="sect2">
<h3 id="sect-Defensive_Coding-CXX-Std-String"><a class="anchor" href="#sect-Defensive_Coding-CXX-Std-String"></a>String Handling with <code>std::string</code></h3>
<div class="paragraph">
<p>The <code>std::string</code> class provides a convenient
way to handle strings. Unlike C strings,
<code>std::string</code> objects have an explicit length
(and can contain embedded NUL characters), and storage for its
characters is managed automatically. This section discusses
<code>std::string</code>, but these observations also
apply to other instances of the
<code>std::basic_string</code> template.</p>
</div>
<div class="paragraph">
<p>The pointer returned by the <code>data()</code> member
function does not necessarily point to a NUL-terminated string.
To obtain a C-compatible string pointer, use
<code>c_str()</code> instead, which adds the NUL
terminator.</p>
</div>
<div class="paragraph">
<p>The pointers returned by the <code>data()</code> and
<code>c_str()</code> functions and iterators are only
valid until certain events happen. It is required that the
exact <code>std::string</code> 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
<code>begin()</code>, in violation of the C++ standard.</p>
</div>
<div class="paragraph">
<p>Particular care is necessary when invoking the
<code>c_str()</code> 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 <code>c_str()</code>
is called completes evaluation. Passing the result of
<code>c_str()</code> to a function which does not store
or otherwise leak that pointer is safe, though.</p>
</div>
<div class="paragraph">
<p>Like with <code>std::vector</code> and
<code>std::array</code>, subscribing with
<code>operator[]</code> does not perform bounds checks.
Use the <code>at(size_type)</code> member function
instead. See <a href="#sect-Defensive_Coding-CXX-Std-Subscript">Containers and <code>operator[]</code></a>.
Furthermore, accessing the terminating NUL character using
<code>operator[]</code> is not possible. (In some
implementations, the <code>c_str()</code> member function
writes the NUL character on demand.)</p>
</div>
<div class="paragraph">
<p>Never write to the pointers returned by
<code>data()</code> or <code>c_str()</code>
after casting away <code>const</code>. If you need a
C-style writable string, use a
<code>std::vector&lt;char&gt;</code> object and its
<code>data()</code> member function. In this case, you
have to explicitly add the terminating NUL character.</p>
</div>
<div class="paragraph">
<p>GCC&#8217;s implementation of <code>std::string</code> 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.</p>
</div>
</div>
<div class="sect2">
<h3 id="sect-Defensive_Coding-CXX-Std-Subscript"><a class="anchor" href="#sect-Defensive_Coding-CXX-Std-Subscript"></a>Containers and <code>operator[]</code></h3>
<div class="paragraph">
<p>Many sequence containers similar to <code>std::vector</code>
provide both <code>operator[](size_type)</code> and a
member function <code>at(size_type)</code>. This applies
to <code>std::vector</code> itself,
<code>std::array</code>, <code>std::string</code>
and other instances of <code>std::basic_string</code>.</p>
</div>
<div class="paragraph">
<p><code>operator[](size_type)</code> is not required by the
standard to perform bounds checking (and the implementation in
GCC does not). In contrast, <code>at(size_type)</code>
must perform such a check. Therefore, in code which is not
performance-critical, you should prefer
<code>at(size_type)</code> over
<code>operator[](size_type)</code>, even though it is
slightly more verbose.</p>
</div>
<div class="paragraph">
<p>The <code>front()</code> and <code>back()</code>
member functions are undefined if a vector object is empty. You
can use <code>vec.at(0)</code> and
<code>vec.at(vec.size() - 1)</code> as checked
replacements. For an empty vector, <code>data()</code> is
defined; it returns an arbitrary pointer, but not necessarily
the NULL pointer.</p>
</div>
</div>
<div class="sect2">
<h3 id="sect-Defensive_Coding-CXX-Std-Iterators"><a class="anchor" href="#sect-Defensive_Coding-CXX-Std-Iterators"></a>Iterators</h3>
<div class="paragraph">
<p>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.</p>
</div>
<div class="paragraph">
<p>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.</p>
</div>
<div class="paragraph">
<p>These issues make some of the standard library functions
difficult to use correctly, see <a href="#sect-Defensive_Coding-CXX-Std-Functions-Unpaired_Iterators">Unpaired Iterators</a>.</p>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<div id="bottom" class="text-muted py-3" >
<div class="foot">
<div class="container">
<div class="row footerlinks">
<div class="col-sm-3 col-xs-6 widget">
<h3 class="widget-title">About</h3>
<div class="widget-body">
<dl>
<dd><a href="https://fedoraproject.org/wiki/Overview">About Fedora</a></dd>
<dd><a href="https://getfedora.org/en/sponsors">Sponsors</a></dd>
<dd><a href="https://fedoramagazine.org">Fedora Magazine</a></dd>
<dd><a href="https://fedoraproject.org/wiki/Legal:Main#Legal">Legal</a></dd>
</dl>
<ul class="list-inline">
<li>
<a href="https://www.facebook.com/TheFedoraProject" class="btn-social btn-outline"><i class="fa fa-fw fa-facebook"></i></a>
</li>
<li>
<a href="https://plus.google.com/112917221531140868607" class="btn-social btn-outline"><i class="fa fa-fw fa-google-plus"></i></a>
</li>
<li>
<a href="https://twitter.com/fedora" class="btn-social btn-outline"><i class="fa fa-fw fa-twitter"></i></a>
</li>
</ul>
</div>
</div>
<div class="col-sm-3 col-xs-6 widget">
<h3 class="widget-title uppercase">Download</h3>
<div class="widget-body">
<dl>
<dd><a href="https://getfedora.org/en/workstation/download">Get Fedora Workstation</a></dd>
<dd><a href="https://getfedora.org/en/server/download">Get Fedora Server</a></dd>
<dd><a href="https://getfedora.org/en/atomic/download">Get Fedora Atomic</a></dd>
<dd><a href="https://spins.fedoraproject.org">Fedora Spins</a></dd>
<dd><a href="https://labs.fedoraproject.org">Fedora Labs</a></dd>
<dd><a href="https://arm.fedoraproject.org">Fedora ARM<span class="sup">&reg;</span></a></dd>
<dd><a href="https://alt.fedoraproject.org/">Alternative Downloads</a></dd>
</dl>
</div>
</div>
<div class="col-sm-3 col-xs-6 widget">
<h3 class="widget-title">Support</h3>
<div class="widget-body">
<dl>
<dd><a href="https://fedoraproject.org/wiki/Communicating_and_getting_help">Get Help</a></dd>
<dd><a href="https://ask.fedoraproject.org/">Ask Fedora</a></dd>
<dd><a href="https://fedoraproject.org/wiki/Common_F27_bugs">Common Bugs</a></dd>
<dd><a href="https://developer.fedoraproject.org/">Fedora Developer Portal</a></dd>
<dd><a href="https://docs.fedoraproject.org/f27/install-guide/index.html">Installation Guide</a></dd>
</dl>
</div>
</div>
<div class="col-sm-3 col-xs-6 widget">
<h3 class="widget-title">Join</h3>
<div class="widget-body">
<dl>
<dd><a href="https://fedoraproject.org/wiki/Join">Join Fedora</a></dd>
<dd><a href="http://fedoraplanet.org">Planet Fedora</a></dd>
<dd><a href="https://fedoraproject.org/wiki/SIGs">Fedora SIGs</a></dd>
<dd><a href="https://admin.fedoraproject.org/accounts/">Fedora Account System</a></dd>
<dd><a href="https://fedoracommunity.org/">Fedora Community</a></dd>
</dl>
</div>
</div>
</div> <!-- /row of widgets -->
<div class="row">
<div class="col-md-2">
<div class="widget-body">
<a href="https://www.redhat.com/"><img class="rh-logo" src="../../../master/_images/redhat-logo.png" alt="Red Hat Logo" /></a>
</div>
</div>
<div class="col-md-7">
<div class="widget-body">
<p class="sponsor">Fedora is sponsored by Red Hat.</p>
<p class="sponsor"><a href="https://www.redhat.com/en/technologies/linux-platforms/articles/relationship-between-fedora-and-rhel">Learn more about the relationship between Red Hat and Fedora &raquo;</a></p>
<p class="copy">&copy; 2017 Red Hat, Inc. and others. Please send any comments or corrections to the <a href="https://pagure.io/fedora-docs/docs-fp-o">documentation team</a></p>
</div>
</div>
</div> <!-- /row of widgets -->
</div>
</div>
</div>
<!-- jQuery (necessary for Bootstrap's JavaScript plugins) -->
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>
<!-- Latest compiled and minified JavaScript -->
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/js/bootstrap.min.js"></script>
<script src="../../../master/_javascripts/bootstrap-offcanvas.js" type="text/javascript"></script>
<script type="text/javascript">
/*<![CDATA[*/
$(document).ready(function() {
$("[id^='topicGroup']").on('show.bs.collapse', function (event) {
if (!($(event.target).attr('id').match(/^topicSubGroup/))) {
$(this).parent().find("[id^='tgSpan']").toggleClass("fa-angle-right fa-angle-down");
}
});
$("[id^='topicGroup']").on('hide.bs.collapse', function (event) {
if (!($(event.target).attr('id').match(/^topicSubGroup/))) {
$(this).parent().find("[id^='tgSpan']").toggleClass("fa-angle-right fa-angle-down");
}
});
$("[id^='topicSubGroup']").on('show.bs.collapse', function () {
$(this).parent().find("[id^='sgSpan']").toggleClass("fa-caret-right fa-caret-down");
});
$("[id^='topicSubGroup']").on('hide.bs.collapse', function () {
$(this).parent().find("[id^='sgSpan']").toggleClass("fa-caret-right fa-caret-down");
});
});
/*]]>*/
</script>
</body>
</html>

View file

@ -1,356 +0,0 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta content="IE=edge" http-equiv="X-UA-Compatible">
<meta content="width=device-width, initial-scale=1.0" name="viewport">
<title>Defensive Coding Guide | Defensive Coding Guide | Programming Languages | The Go Programming Language</title>
<!-- Bootstrap -->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css">
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap-theme.min.css">
<!-- Overpass Font -->
<link rel="stylesheet" href="https://overpass-30e2.kxcdn.com/overpass.css">
<link href="../../../master/_stylesheets/asciibinder.css" rel="stylesheet" />
<!-- HTML5 shim and Respond.js for IE8 support of HTML5 elements and media queries -->
<!-- WARNING: Respond.js doesn't work if you view the page via file:// -->
<!--[if lt IE 9]>
<script src="https://oss.maxcdn.com/html5shiv/3.7.2/html5shiv.min.js"></script>
<script src="https://oss.maxcdn.com/respond/1.4.2/respond.min.js"></script>
<![endif]-->
<link href="../../../master/_images/favicon32x32.png" rel="shortcut icon" type="text/css">
<!--[if IE]><link rel="shortcut icon" href="../../../master/_images/favicon.ico"><![endif]-->
<meta content="AsciiBinder" name="application-name">
</head>
<body>
<div class="navbar navbar-default" role="navigation">
<div class="container-fluid">
<div class="navbar-header">
<a class="navbar-brand" href="https://docs.fedoraproject.org/"><img alt="Fedora Documentation" src="../../../master/_images/fedora.svg"></a>
</div>
</div>
</div>
<div class="container">
<p class="toggle-nav visible-xs pull-left">
<button class="btn btn-default btn-sm" type="button" data-toggle="offcanvas">Toggle nav</button>
</p>
<ol class="breadcrumb">
<li class="sitename">
<a href="../../../index.html">Home</a>
</li>
<li class="hidden-xs active">
<a href="../../en-US/index.html">Defensive Coding Guide </a>
</li>
<li class="hidden-xs active">
<a href="../../en-US/index.html">Defensive Coding Guide</a>
</li>
<li class="hidden-xs active"><a href="../../en-US/programming-languages/C.html">Programming Languages</a></li>
<li class="hidden-xs active">
The Go Programming Language
</li>
</ol>
<div class="row row-offcanvas row-offcanvas-left">
<div class="col-xs-8 col-sm-3 col-md-3 sidebar sidebar-offcanvas">
<ul class="nav nav-sidebar">
<li class="nav-header">
<a class="" href="#" data-toggle="collapse" data-target="#topicGroup0">
<span id="tgSpan0" class="fa fa-angle-down"></span>Defensive Coding Guide
</a>
<ul id="topicGroup0" class="collapse in list-unstyled">
<li><a class="" href="../../en-US/index.html">Book Information</a></li>
<li class="nav-header">
<a class="" href="#" data-toggle="collapse" data-target="#topicSubGroup-0-1">
<span id="sgSpan-0-1" class="fa fa-caret-down"></span>&nbsp;Programming Languages
</a>
<ul id="topicSubGroup-0-1" class="nav-tertiary list-unstyled collapse in">
<li><a class="" href="../../en-US/programming-languages/C.html">The C Programming Language</a></li>
<li><a class="" href="../../en-US/programming-languages/CXX.html">The C++ Programming&nbsp;Language</a></li>
<li><a class="" href="../../en-US/programming-languages/Java.html">The Java Programming Language</a></li>
<li><a class="" href="../../en-US/programming-languages/Python.html">The Python Programming Language</a></li>
<li><a class="" href="../../en-US/programming-languages/Shell.html">Shell Programming and bash</a></li>
<li><a class=" active" href="../../en-US/programming-languages/Go.html">The Go Programming Language</a></li>
<li><a class="" href="../../en-US/programming-languages/Vala.html">The Vala Programming Language</a></li>
</ul>
</li>
<li class="nav-header">
<a class="" href="#" data-toggle="collapse" data-target="#topicSubGroup-0-2">
<span id="sgSpan-0-2" class="fa fa-caret-right"></span>&nbsp;Specific Programming Tasks
</a>
<ul id="topicSubGroup-0-2" class="nav-tertiary list-unstyled collapse">
<li><a class="" href="../../en-US/tasks/Tasks-Library_Design.html">Library Design</a></li>
<li><a class="" href="../../en-US/tasks/Tasks-Descriptors.html">File Descriptor Management</a></li>
<li><a class="" href="../../en-US/tasks/Tasks-File_System.html">File System Manipulation</a></li>
<li><a class="" href="../../en-US/tasks/Tasks-Temporary_Files.html">Temporary Files</a></li>
<li><a class="" href="../../en-US/tasks/Tasks-Processes.html">Processes</a></li>
<li><a class="" href="../../en-US/tasks/Tasks-Serialization.html">Serialization and Deserialization</a></li>
<li><a class="" href="../../en-US/tasks/Tasks-Cryptography.html">Cryptography</a></li>
<li><a class="" href="../../en-US/tasks/Tasks-Packaging.html">RPM Packaging</a></li>
</ul>
</li>
<li class="nav-header">
<a class="" href="#" data-toggle="collapse" data-target="#topicSubGroup-0-3">
<span id="sgSpan-0-3" class="fa fa-caret-right"></span>&nbsp;Implementing Security Features
</a>
<ul id="topicSubGroup-0-3" class="nav-tertiary list-unstyled collapse">
<li><a class="" href="../../en-US/features/Features-Authentication.html">Authentication and Authorization</a></li>
<li><a class="" href="../../en-US/features/Features-TLS.html">Transport Layer Security (TLS)</a></li>
<li><a class="" href="../../en-US/features/Features-HSM.html">Hardware Security Modules and Smart Cards</a></li>
</ul>
</li>
<li><a class="" href="../../en-US/Revision_History.html">Revision History</a></li>
</ul>
</li>
</ul>
</div>
<div class="col-xs-12 col-sm-9 col-md-9 main">
<div class="page-header">
<h2>The Go Programming Language</h2>
</div>
<div id="preamble">
<div class="sectionbody">
<div class="paragraph">
<p>This chapter contains language-specific recommendations for Go.</p>
</div>
</div>
</div>
<div class="sect1">
<h2 id="chap-Defensive_Coding-Go-Memory_Safety"><a class="anchor" href="#chap-Defensive_Coding-Go-Memory_Safety"></a>Memory Safety</h2>
<div class="sectionbody">
<div class="paragraph">
<p>Go provides memory safety, but only if the program is not executed
in parallel (that is, <code>GOMAXPROCS</code> is not larger than
<code>1</code>). 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.</p>
</div>
<div class="paragraph">
<p>Code which does not run in parallel and does not use the
<code>unsafe</code> 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.</p>
</div>
<div class="paragraph">
<p>Keep in mind that finalization can introduce parallelism because
finalizers are executed concurrently, potentially interleaved with
the rest of the program.</p>
</div>
</div>
</div>
<div class="sect1">
<h2 id="chap-Defensive_Coding-Go-Error_Handling"><a class="anchor" href="#chap-Defensive_Coding-Go-Error_Handling"></a>Error Handling</h2>
<div class="sectionbody">
<div class="paragraph">
<p>Only a few common operations (such as pointer dereference, integer
division, array subscripting) trigger exceptions in Go, called
<strong>panics</strong>. Most interfaces in the standard
library use a separate return value of type
<code>error</code> to signal error.</p>
</div>
<div class="paragraph">
<p>Not checking error return values can lead to incorrect operation
and data loss (especially in the case of writes, using interfaces
such as <code>io.Writer</code>).</p>
</div>
<div class="paragraph">
<p>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 <code>nil</code> value, handling any encountered
error. See <a href="#ex-Defensive_Coding-Go-Error_Handling-Regular">Regular error handling in Go</a> for
details.</p>
</div>
<div id="ex-Defensive_Coding-Go-Error_Handling-Regular" class="exampleblock">
<div class="title">Example 1. Regular error handling in Go</div>
<div class="content">
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code data-lang="go">Unresolved directive in &lt;stdin&gt; - include::../snippets/Go-Error_Handling-Regular.adoc[]</code></pre>
</div>
</div>
</div>
</div>
<div class="paragraph">
<p>However, with <code>io.Reader</code>,
<code>io.ReaderAt</code> and related interfaces, it is
necessary to check for a non-zero number of read bytes first, as
shown in <a href="#ex-Defensive_Coding-Go-Error_Handling-IO">Read error handling in Go</a>. If this
pattern is not followed, data loss may occur. This is due to the
fact that the <code>io.Reader</code> interface permits
returning both data and an error at the same time.</p>
</div>
<div id="ex-Defensive_Coding-Go-Error_Handling-IO" class="exampleblock">
<div class="title">Example 2. Read error handling in Go</div>
<div class="content">
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code data-lang="go">Unresolved directive in &lt;stdin&gt; - include::../snippets/Go-Error_Handling-IO.adoc[]</code></pre>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="chap-Defensive_Coding-Go-Garbage_Collector"><a class="anchor" href="#chap-Defensive_Coding-Go-Garbage_Collector"></a>Garbage Collector</h2>
<div class="sectionbody">
<div class="paragraph">
<p>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.</p>
</div>
</div>
</div>
<div class="sect1">
<h2 id="chap-Defensive_Coding-Go-Marshaling"><a class="anchor" href="#chap-Defensive_Coding-Go-Marshaling"></a>Marshaling and Unmarshaling</h2>
<div class="sectionbody">
<div class="paragraph">
<p>Several packages in the <code>encoding</code> hierarchy
provide support for serialization and deserialization. The usual
caveats apply (see
<a href="#chap-Defensive_Coding-Tasks-Serialization">[chap-Defensive_Coding-Tasks-Serialization]</a>).</p>
</div>
<div class="paragraph">
<p>As an additional precaution, the <code>Unmarshal</code>
and <code>Decode</code> functions should only be used with
fresh values in the <code>interface{}</code> 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.</p>
</div>
</div>
</div>
</div>
</div>
</div>
<div id="bottom" class="text-muted py-3" >
<div class="foot">
<div class="container">
<div class="row footerlinks">
<div class="col-sm-3 col-xs-6 widget">
<h3 class="widget-title">About</h3>
<div class="widget-body">
<dl>
<dd><a href="https://fedoraproject.org/wiki/Overview">About Fedora</a></dd>
<dd><a href="https://getfedora.org/en/sponsors">Sponsors</a></dd>
<dd><a href="https://fedoramagazine.org">Fedora Magazine</a></dd>
<dd><a href="https://fedoraproject.org/wiki/Legal:Main#Legal">Legal</a></dd>
</dl>
<ul class="list-inline">
<li>
<a href="https://www.facebook.com/TheFedoraProject" class="btn-social btn-outline"><i class="fa fa-fw fa-facebook"></i></a>
</li>
<li>
<a href="https://plus.google.com/112917221531140868607" class="btn-social btn-outline"><i class="fa fa-fw fa-google-plus"></i></a>
</li>
<li>
<a href="https://twitter.com/fedora" class="btn-social btn-outline"><i class="fa fa-fw fa-twitter"></i></a>
</li>
</ul>
</div>
</div>
<div class="col-sm-3 col-xs-6 widget">
<h3 class="widget-title uppercase">Download</h3>
<div class="widget-body">
<dl>
<dd><a href="https://getfedora.org/en/workstation/download">Get Fedora Workstation</a></dd>
<dd><a href="https://getfedora.org/en/server/download">Get Fedora Server</a></dd>
<dd><a href="https://getfedora.org/en/atomic/download">Get Fedora Atomic</a></dd>
<dd><a href="https://spins.fedoraproject.org">Fedora Spins</a></dd>
<dd><a href="https://labs.fedoraproject.org">Fedora Labs</a></dd>
<dd><a href="https://arm.fedoraproject.org">Fedora ARM<span class="sup">&reg;</span></a></dd>
<dd><a href="https://alt.fedoraproject.org/">Alternative Downloads</a></dd>
</dl>
</div>
</div>
<div class="col-sm-3 col-xs-6 widget">
<h3 class="widget-title">Support</h3>
<div class="widget-body">
<dl>
<dd><a href="https://fedoraproject.org/wiki/Communicating_and_getting_help">Get Help</a></dd>
<dd><a href="https://ask.fedoraproject.org/">Ask Fedora</a></dd>
<dd><a href="https://fedoraproject.org/wiki/Common_F27_bugs">Common Bugs</a></dd>
<dd><a href="https://developer.fedoraproject.org/">Fedora Developer Portal</a></dd>
<dd><a href="https://docs.fedoraproject.org/f27/install-guide/index.html">Installation Guide</a></dd>
</dl>
</div>
</div>
<div class="col-sm-3 col-xs-6 widget">
<h3 class="widget-title">Join</h3>
<div class="widget-body">
<dl>
<dd><a href="https://fedoraproject.org/wiki/Join">Join Fedora</a></dd>
<dd><a href="http://fedoraplanet.org">Planet Fedora</a></dd>
<dd><a href="https://fedoraproject.org/wiki/SIGs">Fedora SIGs</a></dd>
<dd><a href="https://admin.fedoraproject.org/accounts/">Fedora Account System</a></dd>
<dd><a href="https://fedoracommunity.org/">Fedora Community</a></dd>
</dl>
</div>
</div>
</div> <!-- /row of widgets -->
<div class="row">
<div class="col-md-2">
<div class="widget-body">
<a href="https://www.redhat.com/"><img class="rh-logo" src="../../../master/_images/redhat-logo.png" alt="Red Hat Logo" /></a>
</div>
</div>
<div class="col-md-7">
<div class="widget-body">
<p class="sponsor">Fedora is sponsored by Red Hat.</p>
<p class="sponsor"><a href="https://www.redhat.com/en/technologies/linux-platforms/articles/relationship-between-fedora-and-rhel">Learn more about the relationship between Red Hat and Fedora &raquo;</a></p>
<p class="copy">&copy; 2017 Red Hat, Inc. and others. Please send any comments or corrections to the <a href="https://pagure.io/fedora-docs/docs-fp-o">documentation team</a></p>
</div>
</div>
</div> <!-- /row of widgets -->
</div>
</div>
</div>
<!-- jQuery (necessary for Bootstrap's JavaScript plugins) -->
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>
<!-- Latest compiled and minified JavaScript -->
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/js/bootstrap.min.js"></script>
<script src="../../../master/_javascripts/bootstrap-offcanvas.js" type="text/javascript"></script>
<script type="text/javascript">
/*<![CDATA[*/
$(document).ready(function() {
$("[id^='topicGroup']").on('show.bs.collapse', function (event) {
if (!($(event.target).attr('id').match(/^topicSubGroup/))) {
$(this).parent().find("[id^='tgSpan']").toggleClass("fa-angle-right fa-angle-down");
}
});
$("[id^='topicGroup']").on('hide.bs.collapse', function (event) {
if (!($(event.target).attr('id').match(/^topicSubGroup/))) {
$(this).parent().find("[id^='tgSpan']").toggleClass("fa-angle-right fa-angle-down");
}
});
$("[id^='topicSubGroup']").on('show.bs.collapse', function () {
$(this).parent().find("[id^='sgSpan']").toggleClass("fa-caret-right fa-caret-down");
});
$("[id^='topicSubGroup']").on('hide.bs.collapse', function () {
$(this).parent().find("[id^='sgSpan']").toggleClass("fa-caret-right fa-caret-down");
});
});
/*]]>*/
</script>
</body>
</html>

File diff suppressed because it is too large Load diff

View file

@ -1,313 +0,0 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta content="IE=edge" http-equiv="X-UA-Compatible">
<meta content="width=device-width, initial-scale=1.0" name="viewport">
<title>Defensive Coding Guide | Defensive Coding Guide | Programming Languages | The Python Programming Language</title>
<!-- Bootstrap -->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css">
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap-theme.min.css">
<!-- Overpass Font -->
<link rel="stylesheet" href="https://overpass-30e2.kxcdn.com/overpass.css">
<link href="../../../master/_stylesheets/asciibinder.css" rel="stylesheet" />
<!-- HTML5 shim and Respond.js for IE8 support of HTML5 elements and media queries -->
<!-- WARNING: Respond.js doesn't work if you view the page via file:// -->
<!--[if lt IE 9]>
<script src="https://oss.maxcdn.com/html5shiv/3.7.2/html5shiv.min.js"></script>
<script src="https://oss.maxcdn.com/respond/1.4.2/respond.min.js"></script>
<![endif]-->
<link href="../../../master/_images/favicon32x32.png" rel="shortcut icon" type="text/css">
<!--[if IE]><link rel="shortcut icon" href="../../../master/_images/favicon.ico"><![endif]-->
<meta content="AsciiBinder" name="application-name">
</head>
<body>
<div class="navbar navbar-default" role="navigation">
<div class="container-fluid">
<div class="navbar-header">
<a class="navbar-brand" href="https://docs.fedoraproject.org/"><img alt="Fedora Documentation" src="../../../master/_images/fedora.svg"></a>
</div>
</div>
</div>
<div class="container">
<p class="toggle-nav visible-xs pull-left">
<button class="btn btn-default btn-sm" type="button" data-toggle="offcanvas">Toggle nav</button>
</p>
<ol class="breadcrumb">
<li class="sitename">
<a href="../../../index.html">Home</a>
</li>
<li class="hidden-xs active">
<a href="../../en-US/index.html">Defensive Coding Guide </a>
</li>
<li class="hidden-xs active">
<a href="../../en-US/index.html">Defensive Coding Guide</a>
</li>
<li class="hidden-xs active"><a href="../../en-US/programming-languages/C.html">Programming Languages</a></li>
<li class="hidden-xs active">
The Python Programming Language
</li>
</ol>
<div class="row row-offcanvas row-offcanvas-left">
<div class="col-xs-8 col-sm-3 col-md-3 sidebar sidebar-offcanvas">
<ul class="nav nav-sidebar">
<li class="nav-header">
<a class="" href="#" data-toggle="collapse" data-target="#topicGroup0">
<span id="tgSpan0" class="fa fa-angle-down"></span>Defensive Coding Guide
</a>
<ul id="topicGroup0" class="collapse in list-unstyled">
<li><a class="" href="../../en-US/index.html">Book Information</a></li>
<li class="nav-header">
<a class="" href="#" data-toggle="collapse" data-target="#topicSubGroup-0-1">
<span id="sgSpan-0-1" class="fa fa-caret-down"></span>&nbsp;Programming Languages
</a>
<ul id="topicSubGroup-0-1" class="nav-tertiary list-unstyled collapse in">
<li><a class="" href="../../en-US/programming-languages/C.html">The C Programming Language</a></li>
<li><a class="" href="../../en-US/programming-languages/CXX.html">The C++ Programming&nbsp;Language</a></li>
<li><a class="" href="../../en-US/programming-languages/Java.html">The Java Programming Language</a></li>
<li><a class=" active" href="../../en-US/programming-languages/Python.html">The Python Programming Language</a></li>
<li><a class="" href="../../en-US/programming-languages/Shell.html">Shell Programming and bash</a></li>
<li><a class="" href="../../en-US/programming-languages/Go.html">The Go Programming Language</a></li>
<li><a class="" href="../../en-US/programming-languages/Vala.html">The Vala Programming Language</a></li>
</ul>
</li>
<li class="nav-header">
<a class="" href="#" data-toggle="collapse" data-target="#topicSubGroup-0-2">
<span id="sgSpan-0-2" class="fa fa-caret-right"></span>&nbsp;Specific Programming Tasks
</a>
<ul id="topicSubGroup-0-2" class="nav-tertiary list-unstyled collapse">
<li><a class="" href="../../en-US/tasks/Tasks-Library_Design.html">Library Design</a></li>
<li><a class="" href="../../en-US/tasks/Tasks-Descriptors.html">File Descriptor Management</a></li>
<li><a class="" href="../../en-US/tasks/Tasks-File_System.html">File System Manipulation</a></li>
<li><a class="" href="../../en-US/tasks/Tasks-Temporary_Files.html">Temporary Files</a></li>
<li><a class="" href="../../en-US/tasks/Tasks-Processes.html">Processes</a></li>
<li><a class="" href="../../en-US/tasks/Tasks-Serialization.html">Serialization and Deserialization</a></li>
<li><a class="" href="../../en-US/tasks/Tasks-Cryptography.html">Cryptography</a></li>
<li><a class="" href="../../en-US/tasks/Tasks-Packaging.html">RPM Packaging</a></li>
</ul>
</li>
<li class="nav-header">
<a class="" href="#" data-toggle="collapse" data-target="#topicSubGroup-0-3">
<span id="sgSpan-0-3" class="fa fa-caret-right"></span>&nbsp;Implementing Security Features
</a>
<ul id="topicSubGroup-0-3" class="nav-tertiary list-unstyled collapse">
<li><a class="" href="../../en-US/features/Features-Authentication.html">Authentication and Authorization</a></li>
<li><a class="" href="../../en-US/features/Features-TLS.html">Transport Layer Security (TLS)</a></li>
<li><a class="" href="../../en-US/features/Features-HSM.html">Hardware Security Modules and Smart Cards</a></li>
</ul>
</li>
<li><a class="" href="../../en-US/Revision_History.html">Revision History</a></li>
</ul>
</li>
</ul>
</div>
<div class="col-xs-12 col-sm-9 col-md-9 main">
<div class="page-header">
<h2>The Python Programming Language</h2>
</div>
<div id="preamble">
<div class="sectionbody">
<div class="paragraph">
<p>Python provides memory safety by default, so low-level security
vulnerabilities are rare and typically needs fixing the Python
interpreter or standard library itself.</p>
</div>
<div class="paragraph">
<p>Other sections with Python-specific advice include:</p>
</div>
<div class="ulist">
<ul>
<li>
<p><a href="#chap-Defensive_Coding-Tasks-Temporary_Files">[chap-Defensive_Coding-Tasks-Temporary_Files]</a></p>
</li>
<li>
<p><a href="#sect-Defensive_Coding-Tasks-Processes-Creation">[sect-Defensive_Coding-Tasks-Processes-Creation]</a></p>
</li>
<li>
<p><a href="#chap-Defensive_Coding-Tasks-Serialization">[chap-Defensive_Coding-Tasks-Serialization]</a>, in
particular <a href="#sect-Defensive_Coding-Tasks-Serialization-Library">[sect-Defensive_Coding-Tasks-Serialization-Library]</a></p>
</li>
<li>
<p><a href="#sect-Defensive_Coding-Tasks-Cryptography-Randomness">[sect-Defensive_Coding-Tasks-Cryptography-Randomness]</a></p>
</li>
</ul>
</div>
</div>
</div>
<div class="sect1">
<h2 id="dangerous-standard-library-features"><a class="anchor" href="#dangerous-standard-library-features"></a>Dangerous Standard Library Features</h2>
<div class="sectionbody">
<div class="paragraph">
<p>Some areas of the standard library, notably the
<code>ctypes</code> module, do not provide memory safety
guarantees comparable to the rest of Python. If such
functionality is used, the advice in <a href="#sect-Defensive_Coding-C-Language">[sect-Defensive_Coding-C-Language]</a> should be followed.</p>
</div>
</div>
</div>
<div class="sect1">
<h2 id="run-time-compilation-and-code-generation"><a class="anchor" href="#run-time-compilation-and-code-generation"></a>Run-time Compilation and Code Generation</h2>
<div class="sectionbody">
<div class="paragraph">
<p>The following Python functions and statements related to code
execution should be avoided:</p>
</div>
<div class="ulist">
<ul>
<li>
<p><code>compile</code></p>
</li>
<li>
<p><code>eval</code></p>
</li>
<li>
<p><code>exec</code></p>
</li>
<li>
<p><code>execfile</code></p>
</li>
</ul>
</div>
<div class="paragraph">
<p>If you need to parse integers or floating point values, use the
<code>int</code> and <code>float</code>
functions instead of <code>eval</code>. Sandboxing
untrusted Python code does not work reliably.</p>
</div>
</div>
</div>
<div class="sect1">
<h2 id="sandboxing"><a class="anchor" href="#sandboxing"></a>Sandboxing</h2>
<div class="sectionbody">
<div class="paragraph">
<p>The <code>rexec</code> Python module cannot safely sandbox
untrusted code and should not be used. The standard CPython
implementation is not suitable for sandboxing.</p>
</div>
</div>
</div>
</div>
</div>
</div>
<div id="bottom" class="text-muted py-3" >
<div class="foot">
<div class="container">
<div class="row footerlinks">
<div class="col-sm-3 col-xs-6 widget">
<h3 class="widget-title">About</h3>
<div class="widget-body">
<dl>
<dd><a href="https://fedoraproject.org/wiki/Overview">About Fedora</a></dd>
<dd><a href="https://getfedora.org/en/sponsors">Sponsors</a></dd>
<dd><a href="https://fedoramagazine.org">Fedora Magazine</a></dd>
<dd><a href="https://fedoraproject.org/wiki/Legal:Main#Legal">Legal</a></dd>
</dl>
<ul class="list-inline">
<li>
<a href="https://www.facebook.com/TheFedoraProject" class="btn-social btn-outline"><i class="fa fa-fw fa-facebook"></i></a>
</li>
<li>
<a href="https://plus.google.com/112917221531140868607" class="btn-social btn-outline"><i class="fa fa-fw fa-google-plus"></i></a>
</li>
<li>
<a href="https://twitter.com/fedora" class="btn-social btn-outline"><i class="fa fa-fw fa-twitter"></i></a>
</li>
</ul>
</div>
</div>
<div class="col-sm-3 col-xs-6 widget">
<h3 class="widget-title uppercase">Download</h3>
<div class="widget-body">
<dl>
<dd><a href="https://getfedora.org/en/workstation/download">Get Fedora Workstation</a></dd>
<dd><a href="https://getfedora.org/en/server/download">Get Fedora Server</a></dd>
<dd><a href="https://getfedora.org/en/atomic/download">Get Fedora Atomic</a></dd>
<dd><a href="https://spins.fedoraproject.org">Fedora Spins</a></dd>
<dd><a href="https://labs.fedoraproject.org">Fedora Labs</a></dd>
<dd><a href="https://arm.fedoraproject.org">Fedora ARM<span class="sup">&reg;</span></a></dd>
<dd><a href="https://alt.fedoraproject.org/">Alternative Downloads</a></dd>
</dl>
</div>
</div>
<div class="col-sm-3 col-xs-6 widget">
<h3 class="widget-title">Support</h3>
<div class="widget-body">
<dl>
<dd><a href="https://fedoraproject.org/wiki/Communicating_and_getting_help">Get Help</a></dd>
<dd><a href="https://ask.fedoraproject.org/">Ask Fedora</a></dd>
<dd><a href="https://fedoraproject.org/wiki/Common_F27_bugs">Common Bugs</a></dd>
<dd><a href="https://developer.fedoraproject.org/">Fedora Developer Portal</a></dd>
<dd><a href="https://docs.fedoraproject.org/f27/install-guide/index.html">Installation Guide</a></dd>
</dl>
</div>
</div>
<div class="col-sm-3 col-xs-6 widget">
<h3 class="widget-title">Join</h3>
<div class="widget-body">
<dl>
<dd><a href="https://fedoraproject.org/wiki/Join">Join Fedora</a></dd>
<dd><a href="http://fedoraplanet.org">Planet Fedora</a></dd>
<dd><a href="https://fedoraproject.org/wiki/SIGs">Fedora SIGs</a></dd>
<dd><a href="https://admin.fedoraproject.org/accounts/">Fedora Account System</a></dd>
<dd><a href="https://fedoracommunity.org/">Fedora Community</a></dd>
</dl>
</div>
</div>
</div> <!-- /row of widgets -->
<div class="row">
<div class="col-md-2">
<div class="widget-body">
<a href="https://www.redhat.com/"><img class="rh-logo" src="../../../master/_images/redhat-logo.png" alt="Red Hat Logo" /></a>
</div>
</div>
<div class="col-md-7">
<div class="widget-body">
<p class="sponsor">Fedora is sponsored by Red Hat.</p>
<p class="sponsor"><a href="https://www.redhat.com/en/technologies/linux-platforms/articles/relationship-between-fedora-and-rhel">Learn more about the relationship between Red Hat and Fedora &raquo;</a></p>
<p class="copy">&copy; 2017 Red Hat, Inc. and others. Please send any comments or corrections to the <a href="https://pagure.io/fedora-docs/docs-fp-o">documentation team</a></p>
</div>
</div>
</div> <!-- /row of widgets -->
</div>
</div>
</div>
<!-- jQuery (necessary for Bootstrap's JavaScript plugins) -->
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>
<!-- Latest compiled and minified JavaScript -->
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/js/bootstrap.min.js"></script>
<script src="../../../master/_javascripts/bootstrap-offcanvas.js" type="text/javascript"></script>
<script type="text/javascript">
/*<![CDATA[*/
$(document).ready(function() {
$("[id^='topicGroup']").on('show.bs.collapse', function (event) {
if (!($(event.target).attr('id').match(/^topicSubGroup/))) {
$(this).parent().find("[id^='tgSpan']").toggleClass("fa-angle-right fa-angle-down");
}
});
$("[id^='topicGroup']").on('hide.bs.collapse', function (event) {
if (!($(event.target).attr('id').match(/^topicSubGroup/))) {
$(this).parent().find("[id^='tgSpan']").toggleClass("fa-angle-right fa-angle-down");
}
});
$("[id^='topicSubGroup']").on('show.bs.collapse', function () {
$(this).parent().find("[id^='sgSpan']").toggleClass("fa-caret-right fa-caret-down");
});
$("[id^='topicSubGroup']").on('hide.bs.collapse', function () {
$(this).parent().find("[id^='sgSpan']").toggleClass("fa-caret-right fa-caret-down");
});
});
/*]]>*/
</script>
</body>
</html>

View file

@ -1,699 +0,0 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta content="IE=edge" http-equiv="X-UA-Compatible">
<meta content="width=device-width, initial-scale=1.0" name="viewport">
<title>Defensive Coding Guide | Defensive Coding Guide | Programming Languages | Shell Programming and bash</title>
<!-- Bootstrap -->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css">
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap-theme.min.css">
<!-- Overpass Font -->
<link rel="stylesheet" href="https://overpass-30e2.kxcdn.com/overpass.css">
<link href="../../../master/_stylesheets/asciibinder.css" rel="stylesheet" />
<!-- HTML5 shim and Respond.js for IE8 support of HTML5 elements and media queries -->
<!-- WARNING: Respond.js doesn't work if you view the page via file:// -->
<!--[if lt IE 9]>
<script src="https://oss.maxcdn.com/html5shiv/3.7.2/html5shiv.min.js"></script>
<script src="https://oss.maxcdn.com/respond/1.4.2/respond.min.js"></script>
<![endif]-->
<link href="../../../master/_images/favicon32x32.png" rel="shortcut icon" type="text/css">
<!--[if IE]><link rel="shortcut icon" href="../../../master/_images/favicon.ico"><![endif]-->
<meta content="AsciiBinder" name="application-name">
</head>
<body>
<div class="navbar navbar-default" role="navigation">
<div class="container-fluid">
<div class="navbar-header">
<a class="navbar-brand" href="https://docs.fedoraproject.org/"><img alt="Fedora Documentation" src="../../../master/_images/fedora.svg"></a>
</div>
</div>
</div>
<div class="container">
<p class="toggle-nav visible-xs pull-left">
<button class="btn btn-default btn-sm" type="button" data-toggle="offcanvas">Toggle nav</button>
</p>
<ol class="breadcrumb">
<li class="sitename">
<a href="../../../index.html">Home</a>
</li>
<li class="hidden-xs active">
<a href="../../en-US/index.html">Defensive Coding Guide </a>
</li>
<li class="hidden-xs active">
<a href="../../en-US/index.html">Defensive Coding Guide</a>
</li>
<li class="hidden-xs active"><a href="../../en-US/programming-languages/C.html">Programming Languages</a></li>
<li class="hidden-xs active">
Shell Programming and bash
</li>
</ol>
<div class="row row-offcanvas row-offcanvas-left">
<div class="col-xs-8 col-sm-3 col-md-3 sidebar sidebar-offcanvas">
<ul class="nav nav-sidebar">
<li class="nav-header">
<a class="" href="#" data-toggle="collapse" data-target="#topicGroup0">
<span id="tgSpan0" class="fa fa-angle-down"></span>Defensive Coding Guide
</a>
<ul id="topicGroup0" class="collapse in list-unstyled">
<li><a class="" href="../../en-US/index.html">Book Information</a></li>
<li class="nav-header">
<a class="" href="#" data-toggle="collapse" data-target="#topicSubGroup-0-1">
<span id="sgSpan-0-1" class="fa fa-caret-down"></span>&nbsp;Programming Languages
</a>
<ul id="topicSubGroup-0-1" class="nav-tertiary list-unstyled collapse in">
<li><a class="" href="../../en-US/programming-languages/C.html">The C Programming Language</a></li>
<li><a class="" href="../../en-US/programming-languages/CXX.html">The C++ Programming&nbsp;Language</a></li>
<li><a class="" href="../../en-US/programming-languages/Java.html">The Java Programming Language</a></li>
<li><a class="" href="../../en-US/programming-languages/Python.html">The Python Programming Language</a></li>
<li><a class=" active" href="../../en-US/programming-languages/Shell.html">Shell Programming and bash</a></li>
<li><a class="" href="../../en-US/programming-languages/Go.html">The Go Programming Language</a></li>
<li><a class="" href="../../en-US/programming-languages/Vala.html">The Vala Programming Language</a></li>
</ul>
</li>
<li class="nav-header">
<a class="" href="#" data-toggle="collapse" data-target="#topicSubGroup-0-2">
<span id="sgSpan-0-2" class="fa fa-caret-right"></span>&nbsp;Specific Programming Tasks
</a>
<ul id="topicSubGroup-0-2" class="nav-tertiary list-unstyled collapse">
<li><a class="" href="../../en-US/tasks/Tasks-Library_Design.html">Library Design</a></li>
<li><a class="" href="../../en-US/tasks/Tasks-Descriptors.html">File Descriptor Management</a></li>
<li><a class="" href="../../en-US/tasks/Tasks-File_System.html">File System Manipulation</a></li>
<li><a class="" href="../../en-US/tasks/Tasks-Temporary_Files.html">Temporary Files</a></li>
<li><a class="" href="../../en-US/tasks/Tasks-Processes.html">Processes</a></li>
<li><a class="" href="../../en-US/tasks/Tasks-Serialization.html">Serialization and Deserialization</a></li>
<li><a class="" href="../../en-US/tasks/Tasks-Cryptography.html">Cryptography</a></li>
<li><a class="" href="../../en-US/tasks/Tasks-Packaging.html">RPM Packaging</a></li>
</ul>
</li>
<li class="nav-header">
<a class="" href="#" data-toggle="collapse" data-target="#topicSubGroup-0-3">
<span id="sgSpan-0-3" class="fa fa-caret-right"></span>&nbsp;Implementing Security Features
</a>
<ul id="topicSubGroup-0-3" class="nav-tertiary list-unstyled collapse">
<li><a class="" href="../../en-US/features/Features-Authentication.html">Authentication and Authorization</a></li>
<li><a class="" href="../../en-US/features/Features-TLS.html">Transport Layer Security (TLS)</a></li>
<li><a class="" href="../../en-US/features/Features-HSM.html">Hardware Security Modules and Smart Cards</a></li>
</ul>
</li>
<li><a class="" href="../../en-US/Revision_History.html">Revision History</a></li>
</ul>
</li>
</ul>
</div>
<div class="col-xs-12 col-sm-9 col-md-9 main">
<div class="page-header">
<h2>Shell Programming and <strong class="application">bash</strong></h2>
</div>
<div id="preamble">
<div class="sectionbody">
<div class="paragraph">
<p>This chapter contains advice about shell programming, specifically
in <strong class="application">bash</strong>. 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.</p>
</div>
</div>
</div>
<div class="sect1">
<h2 id="sect-Defensive_Coding-Shell-Alternatives"><a class="anchor" href="#sect-Defensive_Coding-Shell-Alternatives"></a>Consider Alternatives</h2>
<div class="sectionbody">
<div class="paragraph">
<p>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?</p>
</div>
<div class="paragraph">
<p>For example, Python with its <code>subprocess</code> 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.</p>
</div>
</div>
</div>
<div class="sect1">
<h2 id="sect-Defensive_Coding-Shell-Language"><a class="anchor" href="#sect-Defensive_Coding-Shell-Language"></a>Shell Language Features</h2>
<div class="sectionbody">
<div class="paragraph">
<p>The following sections cover subtleties concerning the shell
programming languages. They have been written with the
<strong class="application">bash</strong> shell in mind, but some of these
features apply to other shells as well.</p>
</div>
<div class="paragraph">
<p>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.</p>
</div>
<div class="sect2">
<h3 id="sect-Defensive_Coding-Shell-Parameter_Expansion"><a class="anchor" href="#sect-Defensive_Coding-Shell-Parameter_Expansion"></a>Parameter Expansion</h3>
<div class="paragraph">
<p>The mechanism by which named shell variables and parameters are
expanded is called <strong>parameter expansion</strong>. The
most basic syntax is
<code>$</code><strong>variable</strong>” or
<code>${</code><strong>variable</strong><code>}</code>”.</p>
</div>
<div class="paragraph">
<p>In almost all cases, a parameter expansion should be enclosed in
double quotation marks <code>&#8220;&#8221;</code>.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code data-lang="bash">external-program &quot;$arg1&quot; &quot;$arg2&quot;</code></pre>
</div>
</div>
<div class="paragraph">
<p>If the double quotation marks are omitted, the value of the
variable will be split according to the current value of the
<code>IFS</code> variable. This may allow the injection of
additional options which are then processed by
<code>external-program</code>.</p>
</div>
<div class="paragraph">
<p>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 <a href="#sect-Defensive_Coding-Shell-Arithmetic">Arithmetic Evaluation</a>.</p>
</div>
</div>
<div class="sect2">
<h3 id="sect-Defensive_Coding-Shell-Double_Expansion"><a class="anchor" href="#sect-Defensive_Coding-Shell-Double_Expansion"></a>Double Expansion</h3>
<div class="paragraph">
<p><strong>Double expansion</strong> occurs when, during the
expansion of a shell variable, not just the variable is expanded,
replacing it by its value, but the <strong>value</strong> 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.</p>
</div>
<div class="paragraph">
<p>The evaluation process is in fact recursive, so a self-referential
expression can cause an out-of-memory condition and a shell crash.</p>
</div>
<div class="paragraph">
<p>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.</p>
</div>
<div class="paragraph">
<p>Double expansion can be requested explicitly with the
<code>eval</code> built-in command, or by invoking a
subshell with “<code>bash -c</code>”. These constructs
should not be used.</p>
</div>
<div class="paragraph">
<p>The following sections give examples of places where implicit
double expansion occurs.</p>
</div>
<div class="sect3">
<h4 id="sect-Defensive_Coding-Shell-Arithmetic"><a class="anchor" href="#sect-Defensive_Coding-Shell-Arithmetic"></a>Arithmetic Evaluation</h4>
<div class="paragraph">
<p><strong>Arithmetic evaluation</strong> 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 <a href="#sect-Defensive_Coding-Shell-Double_Expansion">Double Expansion</a>), 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.</p>
</div>
<div class="paragraph">
<p>Arithmetic evaluation is triggered by the follow constructs:</p>
</div>
<div class="ulist">
<ul>
<li>
<p>The <strong>expression</strong> in
<code>$</code><strong>expression</strong><code></code>
is evaluated. This construct is called <strong>arithmetic
expansion</strong>.</p>
</li>
<li>
<p></p>
<div class="paragraph">
<p><code>$[</code><strong>expression</strong><code>]</code>
is a deprecated syntax with the same effect.</p>
</div>
</li>
<li>
<p>The arguments to the <code>let</code> shell built-in
are evaluated.</p>
</li>
<li>
<p></p>
<div class="paragraph">
<p><code></code><strong>expression</strong><code></code>
is an alternative syntax for “<code>let</code> <strong>expression</strong>”.</p>
</div>
</li>
<li>
<p>Conditional expressions surrounded by
<code>[[</code><code>]]</code>” can trigger
arithmetic evaluation if certain operators such as
<code>-eq</code> are used. (The
<code>test</code> built-in does not perform arithmetic
evaluation, even with integer operators such as
<code>-eq</code>.)</p>
<div class="paragraph">
<p>The conditional expression
<code>[[ $</code><strong>variable</strong> <code>=~</code> <strong>regexp</strong> <code>]]</code>
can be used for input validation, assuming that
<strong>regexp</strong> is a constant regular
expression.
See <a href="#sect-Defensive_Coding-Shell-Input_Validation">Performing Input Validation</a>.</p>
</div>
</li>
<li>
<p>Certain parameter expansions, for example
<code>${</code><strong>variable</strong><code>[</code><strong>expression</strong><code>]}</code>
(array indexing) or
<code>${</code><strong>variable</strong><code>:</code><strong>expression</strong><code>}</code>
(string slicing), trigger arithmetic evaluation of
<strong>expression</strong>.</p>
</li>
<li>
<p>Assignment to array elements using
<strong>array_variable</strong><code>[</code><strong>subscript</strong><code>]=</code><strong>expression</strong>
triggers evaluation of <strong>subscript</strong>, but
not <strong>expression</strong>.</p>
</li>
<li>
<p>The expressions in the arithmetic <code>for</code>
command,
<code>for </code><strong>expression1</strong><code>;</code> <strong>expression2</strong><code>;</code> <strong>expression3</strong><code>; do</code> <strong>commands</strong><code>; done</code>
are evaluated. This does not apply to the regular
for command,
<code>for</code> <strong>variable</strong> <code>in</code> <strong>list</strong><code>; do</code> <strong>commands</strong><code>; done</code>”.</p>
</li>
</ul>
</div>
<div class="admonitionblock important">
<table>
<tr>
<td class="icon">
<i class="fa icon-important" title="Important"></i>
</td>
<td class="content">
<div class="paragraph">
<p>Depending on the <strong class="application">bash</strong> version, the
above list may be incomplete.</p>
</div>
<div class="paragraph">
<p>If faced with a situation where using such shell features
appears necessary, see <a href="#sect-Defensive_Coding-Shell-Alternatives">Consider Alternatives</a>.</p>
</div>
</td>
</tr>
</table>
</div>
<div class="paragraph">
<p>If it is impossible to avoid shell arithmetic on untrusted
inputs, refer to <a href="#sect-Defensive_Coding-Shell-Input_Validation">Performing Input Validation</a>.</p>
</div>
</div>
<div class="sect3">
<h4 id="sect-Defensive_Coding-Shell-Types"><a class="anchor" href="#sect-Defensive_Coding-Shell-Types"></a>Type declarations</h4>
<div class="paragraph">
<p><strong class="application">bash</strong> supports explicit type
declarations for shell variables:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code data-lang="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</code></pre>
</div>
</div>
<div class="paragraph">
<p>Variables can also be declared as arrays by assigning them an
array expression, as in:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code data-lang="bash">array_variable=(1 2 3 4)</code></pre>
</div>
</div>
<div class="paragraph">
<p>Some built-ins (such as <code>mapfile</code>) can
implicitly create array variables.</p>
</div>
<div class="paragraph">
<p>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 <a href="#sect-Defensive_Coding-Shell-Arithmetic">Arithmetic Evaluation</a>.</p>
</div>
<div class="paragraph">
<p>Shell scripts which use integer or array variables should be
rewritten in another, more suitable language. Se <a href="#sect-Defensive_Coding-Shell-Alternatives">Consider Alternatives</a>.</p>
</div>
</div>
</div>
<div class="sect2">
<h3 id="sect-Defensive_Coding-Shell-Obscure"><a class="anchor" href="#sect-Defensive_Coding-Shell-Obscure"></a>Other Obscurities</h3>
<div class="paragraph">
<p>Obscure shell language features should not be used. Examples are:</p>
</div>
<div class="ulist">
<ul>
<li>
<p>Exported functions (<code>export -f</code> or
<code>declare -f</code>).</p>
</li>
<li>
<p>Function names which are not valid variable names, such as
<code>module::function</code>”.</p>
</li>
<li>
<p>The possibility to override built-ins or external commands
with shell functions.</p>
</li>
<li>
<p>Changing the value of the <code>IFS</code> variable to
tokenize strings.</p>
</li>
</ul>
</div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="sect-Defensive_Coding-Shell-Invoke"><a class="anchor" href="#sect-Defensive_Coding-Shell-Invoke"></a>Invoking External Commands</h2>
<div class="sectionbody">
<div class="paragraph">
<p>When passing shell variables as single command line arguments,
they should always be surrounded by double quotes. See
<a href="#sect-Defensive_Coding-Shell-Parameter_Expansion">Parameter Expansion</a>.</p>
</div>
<div class="paragraph">
<p>Care is required when passing untrusted values as positional
parameters to external commands. If the value starts with a hyphen
<code>-</code>”, it may be interpreted by the external
command as an option. Depending on the external program, a
<code>--</code>” 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.)</p>
</div>
<div class="paragraph">
<p>Cleaning the environment before invoking child processes is
difficult to implement in script. <strong class="application">bash</strong>
keeps a hidden list of environment variables which do not correspond
to shell variables, and unsetting them from within a
<strong class="application">bash</strong> script is not possible. To reset
the environment, a script can re-run itself under the “<code>env
-i</code>” 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 “<code>env -i</code>”.</p>
</div>
<div class="admonitionblock important">
<table>
<tr>
<td class="icon">
<i class="fa icon-important" title="Important"></i>
</td>
<td class="content">
<div class="paragraph">
<p>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.</p>
</div>
</td>
</tr>
</table>
</div>
<div class="paragraph">
<p>Checking for failures in executed external commands is recommended.
If no elaborate error recovery is needed, invoking “<code>set
-e</code>” may be sufficient. This causes the script to stop on
the first failed command. However, failures in pipes
(“<code>command1 | command2</code>”) are only detected for the
last command in the pipe, errors in previous commands are ignored.
This can be changed by invoking “<code>set -o pipefail</code>”.
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.</p>
</div>
<div class="paragraph">
<p>See <a href="#sect-Defensive_Coding-Tasks-Processes-Creation">[sect-Defensive_Coding-Tasks-Processes-Creation]</a>
for additional details on creating child processes.</p>
</div>
</div>
</div>
<div class="sect1">
<h2 id="sect-Defensive_Coding-Shell-Temporary_Files"><a class="anchor" href="#sect-Defensive_Coding-Shell-Temporary_Files"></a>Temporary Files</h2>
<div class="sectionbody">
<div class="paragraph">
<p>Temporary files should be created with the
<code>mktemp</code> command, and temporary directories with
<code>mktemp -d</code>”.</p>
</div>
<div class="paragraph">
<p>To clean up temporary files and directories, write a clean-up
shell function and register it as a trap handler, as shown in
<a href="#ex-Defensive_Coding-Tasks-Temporary_Files">Creating and Cleaning up Temporary Files</a>.
Using a separate function avoids issues with proper quoting of
variables.</p>
</div>
<div id="ex-Defensive_Coding-Tasks-Temporary_Files" class="exampleblock">
<div class="title">Example 1. Creating and Cleaning up Temporary Files</div>
<div class="content">
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code data-lang="bash">tmpfile=&quot;$(mktemp)&quot;
cleanup () {
rm -f -- &quot;$tmpfile&quot;
}
trap cleanup 0</code></pre>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="sect-Defensive_Coding-Shell-Input_Validation"><a class="anchor" href="#sect-Defensive_Coding-Shell-Input_Validation"></a>Performing Input Validation</h2>
<div class="sectionbody">
<div class="paragraph">
<p>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 <a href="#sect-Defensive_Coding-Shell-Arithmetic">Arithmetic Evaluation</a>.</p>
</div>
<div class="paragraph">
<p><a href="#ex-Defensive_Coding-Shell-Input_Validation">Input validation in <strong class="application">bash</strong></a>
shows a construct which can be used to check if a string
<code>$value</code>” is an integer. This construct is
specific to <strong class="application">bash</strong> and not portable to
POSIX shells.</p>
</div>
<div id="ex-Defensive_Coding-Shell-Input_Validation" class="exampleblock">
<div class="title">Example 2. Input validation in <strong class="application">bash</strong></div>
<div class="content">
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code data-lang="bash">Unresolved directive in &lt;stdin&gt; - include::../snippets/Shell-Input_Validation.adoc[]</code></pre>
</div>
</div>
</div>
</div>
<div class="paragraph">
<p>Using <code>case</code> 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.</p>
</div>
<div class="paragraph">
<p>The <code>expr</code> external command can give misleading
results (e.g., if the value being checked contains operators
itself) and should not be used.</p>
</div>
</div>
</div>
<div class="sect1">
<h2 id="sect-Defensive_Coding-Shell-Edit_Guard"><a class="anchor" href="#sect-Defensive_Coding-Shell-Edit_Guard"></a>Guarding Shell Scripts Against Changes</h2>
<div class="sectionbody">
<div class="paragraph">
<p><strong class="application">bash</strong> 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.)</p>
</div>
<div class="paragraph">
<p>Therefore, long-running scripts should be guarded against
concurrent modification by putting as much of the program logic
into a <code>main</code> function, and invoking the
<code>main</code> function at the end of the script, using
this syntax:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code data-lang="bash">main &quot;$@&quot; ; exit $?</code></pre>
</div>
</div>
<div class="paragraph">
<p>This construct ensures that <strong class="application">bash</strong> will
stop execution after the <code>main</code> function, instead
of opening the script file and trying to read more commands.</p>
</div>
</div>
</div>
</div>
</div>
</div>
<div id="bottom" class="text-muted py-3" >
<div class="foot">
<div class="container">
<div class="row footerlinks">
<div class="col-sm-3 col-xs-6 widget">
<h3 class="widget-title">About</h3>
<div class="widget-body">
<dl>
<dd><a href="https://fedoraproject.org/wiki/Overview">About Fedora</a></dd>
<dd><a href="https://getfedora.org/en/sponsors">Sponsors</a></dd>
<dd><a href="https://fedoramagazine.org">Fedora Magazine</a></dd>
<dd><a href="https://fedoraproject.org/wiki/Legal:Main#Legal">Legal</a></dd>
</dl>
<ul class="list-inline">
<li>
<a href="https://www.facebook.com/TheFedoraProject" class="btn-social btn-outline"><i class="fa fa-fw fa-facebook"></i></a>
</li>
<li>
<a href="https://plus.google.com/112917221531140868607" class="btn-social btn-outline"><i class="fa fa-fw fa-google-plus"></i></a>
</li>
<li>
<a href="https://twitter.com/fedora" class="btn-social btn-outline"><i class="fa fa-fw fa-twitter"></i></a>
</li>
</ul>
</div>
</div>
<div class="col-sm-3 col-xs-6 widget">
<h3 class="widget-title uppercase">Download</h3>
<div class="widget-body">
<dl>
<dd><a href="https://getfedora.org/en/workstation/download">Get Fedora Workstation</a></dd>
<dd><a href="https://getfedora.org/en/server/download">Get Fedora Server</a></dd>
<dd><a href="https://getfedora.org/en/atomic/download">Get Fedora Atomic</a></dd>
<dd><a href="https://spins.fedoraproject.org">Fedora Spins</a></dd>
<dd><a href="https://labs.fedoraproject.org">Fedora Labs</a></dd>
<dd><a href="https://arm.fedoraproject.org">Fedora ARM<span class="sup">&reg;</span></a></dd>
<dd><a href="https://alt.fedoraproject.org/">Alternative Downloads</a></dd>
</dl>
</div>
</div>
<div class="col-sm-3 col-xs-6 widget">
<h3 class="widget-title">Support</h3>
<div class="widget-body">
<dl>
<dd><a href="https://fedoraproject.org/wiki/Communicating_and_getting_help">Get Help</a></dd>
<dd><a href="https://ask.fedoraproject.org/">Ask Fedora</a></dd>
<dd><a href="https://fedoraproject.org/wiki/Common_F27_bugs">Common Bugs</a></dd>
<dd><a href="https://developer.fedoraproject.org/">Fedora Developer Portal</a></dd>
<dd><a href="https://docs.fedoraproject.org/f27/install-guide/index.html">Installation Guide</a></dd>
</dl>
</div>
</div>
<div class="col-sm-3 col-xs-6 widget">
<h3 class="widget-title">Join</h3>
<div class="widget-body">
<dl>
<dd><a href="https://fedoraproject.org/wiki/Join">Join Fedora</a></dd>
<dd><a href="http://fedoraplanet.org">Planet Fedora</a></dd>
<dd><a href="https://fedoraproject.org/wiki/SIGs">Fedora SIGs</a></dd>
<dd><a href="https://admin.fedoraproject.org/accounts/">Fedora Account System</a></dd>
<dd><a href="https://fedoracommunity.org/">Fedora Community</a></dd>
</dl>
</div>
</div>
</div> <!-- /row of widgets -->
<div class="row">
<div class="col-md-2">
<div class="widget-body">
<a href="https://www.redhat.com/"><img class="rh-logo" src="../../../master/_images/redhat-logo.png" alt="Red Hat Logo" /></a>
</div>
</div>
<div class="col-md-7">
<div class="widget-body">
<p class="sponsor">Fedora is sponsored by Red Hat.</p>
<p class="sponsor"><a href="https://www.redhat.com/en/technologies/linux-platforms/articles/relationship-between-fedora-and-rhel">Learn more about the relationship between Red Hat and Fedora &raquo;</a></p>
<p class="copy">&copy; 2017 Red Hat, Inc. and others. Please send any comments or corrections to the <a href="https://pagure.io/fedora-docs/docs-fp-o">documentation team</a></p>
</div>
</div>
</div> <!-- /row of widgets -->
</div>
</div>
</div>
<!-- jQuery (necessary for Bootstrap's JavaScript plugins) -->
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>
<!-- Latest compiled and minified JavaScript -->
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/js/bootstrap.min.js"></script>
<script src="../../../master/_javascripts/bootstrap-offcanvas.js" type="text/javascript"></script>
<script type="text/javascript">
/*<![CDATA[*/
$(document).ready(function() {
$("[id^='topicGroup']").on('show.bs.collapse', function (event) {
if (!($(event.target).attr('id').match(/^topicSubGroup/))) {
$(this).parent().find("[id^='tgSpan']").toggleClass("fa-angle-right fa-angle-down");
}
});
$("[id^='topicGroup']").on('hide.bs.collapse', function (event) {
if (!($(event.target).attr('id').match(/^topicSubGroup/))) {
$(this).parent().find("[id^='tgSpan']").toggleClass("fa-angle-right fa-angle-down");
}
});
$("[id^='topicSubGroup']").on('show.bs.collapse', function () {
$(this).parent().find("[id^='sgSpan']").toggleClass("fa-caret-right fa-caret-down");
});
$("[id^='topicSubGroup']").on('hide.bs.collapse', function () {
$(this).parent().find("[id^='sgSpan']").toggleClass("fa-caret-right fa-caret-down");
});
});
/*]]>*/
</script>
</body>
</html>

View file

@ -1,273 +0,0 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta content="IE=edge" http-equiv="X-UA-Compatible">
<meta content="width=device-width, initial-scale=1.0" name="viewport">
<title>Defensive Coding Guide | Defensive Coding Guide | Programming Languages | The Vala Programming Language</title>
<!-- Bootstrap -->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css">
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap-theme.min.css">
<!-- Overpass Font -->
<link rel="stylesheet" href="https://overpass-30e2.kxcdn.com/overpass.css">
<link href="../../../master/_stylesheets/asciibinder.css" rel="stylesheet" />
<!-- HTML5 shim and Respond.js for IE8 support of HTML5 elements and media queries -->
<!-- WARNING: Respond.js doesn't work if you view the page via file:// -->
<!--[if lt IE 9]>
<script src="https://oss.maxcdn.com/html5shiv/3.7.2/html5shiv.min.js"></script>
<script src="https://oss.maxcdn.com/respond/1.4.2/respond.min.js"></script>
<![endif]-->
<link href="../../../master/_images/favicon32x32.png" rel="shortcut icon" type="text/css">
<!--[if IE]><link rel="shortcut icon" href="../../../master/_images/favicon.ico"><![endif]-->
<meta content="AsciiBinder" name="application-name">
</head>
<body>
<div class="navbar navbar-default" role="navigation">
<div class="container-fluid">
<div class="navbar-header">
<a class="navbar-brand" href="https://docs.fedoraproject.org/"><img alt="Fedora Documentation" src="../../../master/_images/fedora.svg"></a>
</div>
</div>
</div>
<div class="container">
<p class="toggle-nav visible-xs pull-left">
<button class="btn btn-default btn-sm" type="button" data-toggle="offcanvas">Toggle nav</button>
</p>
<ol class="breadcrumb">
<li class="sitename">
<a href="../../../index.html">Home</a>
</li>
<li class="hidden-xs active">
<a href="../../en-US/index.html">Defensive Coding Guide </a>
</li>
<li class="hidden-xs active">
<a href="../../en-US/index.html">Defensive Coding Guide</a>
</li>
<li class="hidden-xs active"><a href="../../en-US/programming-languages/C.html">Programming Languages</a></li>
<li class="hidden-xs active">
The Vala Programming Language
</li>
</ol>
<div class="row row-offcanvas row-offcanvas-left">
<div class="col-xs-8 col-sm-3 col-md-3 sidebar sidebar-offcanvas">
<ul class="nav nav-sidebar">
<li class="nav-header">
<a class="" href="#" data-toggle="collapse" data-target="#topicGroup0">
<span id="tgSpan0" class="fa fa-angle-down"></span>Defensive Coding Guide
</a>
<ul id="topicGroup0" class="collapse in list-unstyled">
<li><a class="" href="../../en-US/index.html">Book Information</a></li>
<li class="nav-header">
<a class="" href="#" data-toggle="collapse" data-target="#topicSubGroup-0-1">
<span id="sgSpan-0-1" class="fa fa-caret-down"></span>&nbsp;Programming Languages
</a>
<ul id="topicSubGroup-0-1" class="nav-tertiary list-unstyled collapse in">
<li><a class="" href="../../en-US/programming-languages/C.html">The C Programming Language</a></li>
<li><a class="" href="../../en-US/programming-languages/CXX.html">The C++ Programming&nbsp;Language</a></li>
<li><a class="" href="../../en-US/programming-languages/Java.html">The Java Programming Language</a></li>
<li><a class="" href="../../en-US/programming-languages/Python.html">The Python Programming Language</a></li>
<li><a class="" href="../../en-US/programming-languages/Shell.html">Shell Programming and bash</a></li>
<li><a class="" href="../../en-US/programming-languages/Go.html">The Go Programming Language</a></li>
<li><a class=" active" href="../../en-US/programming-languages/Vala.html">The Vala Programming Language</a></li>
</ul>
</li>
<li class="nav-header">
<a class="" href="#" data-toggle="collapse" data-target="#topicSubGroup-0-2">
<span id="sgSpan-0-2" class="fa fa-caret-right"></span>&nbsp;Specific Programming Tasks
</a>
<ul id="topicSubGroup-0-2" class="nav-tertiary list-unstyled collapse">
<li><a class="" href="../../en-US/tasks/Tasks-Library_Design.html">Library Design</a></li>
<li><a class="" href="../../en-US/tasks/Tasks-Descriptors.html">File Descriptor Management</a></li>
<li><a class="" href="../../en-US/tasks/Tasks-File_System.html">File System Manipulation</a></li>
<li><a class="" href="../../en-US/tasks/Tasks-Temporary_Files.html">Temporary Files</a></li>
<li><a class="" href="../../en-US/tasks/Tasks-Processes.html">Processes</a></li>
<li><a class="" href="../../en-US/tasks/Tasks-Serialization.html">Serialization and Deserialization</a></li>
<li><a class="" href="../../en-US/tasks/Tasks-Cryptography.html">Cryptography</a></li>
<li><a class="" href="../../en-US/tasks/Tasks-Packaging.html">RPM Packaging</a></li>
</ul>
</li>
<li class="nav-header">
<a class="" href="#" data-toggle="collapse" data-target="#topicSubGroup-0-3">
<span id="sgSpan-0-3" class="fa fa-caret-right"></span>&nbsp;Implementing Security Features
</a>
<ul id="topicSubGroup-0-3" class="nav-tertiary list-unstyled collapse">
<li><a class="" href="../../en-US/features/Features-Authentication.html">Authentication and Authorization</a></li>
<li><a class="" href="../../en-US/features/Features-TLS.html">Transport Layer Security (TLS)</a></li>
<li><a class="" href="../../en-US/features/Features-HSM.html">Hardware Security Modules and Smart Cards</a></li>
</ul>
</li>
<li><a class="" href="../../en-US/Revision_History.html">Revision History</a></li>
</ul>
</li>
</ul>
</div>
<div class="col-xs-12 col-sm-9 col-md-9 main">
<div class="page-header">
<h2>The Vala Programming Language</h2>
</div>
<div class="paragraph">
<p>Vala is a programming language mainly targeted at GNOME developers.</p>
</div>
<div class="paragraph">
<p>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 <a href="#chap-Defensive_Coding-C">[chap-Defensive_Coding-C]</a> apply.</p>
</div>
<div class="paragraph">
<p>In particular, the following Vala language constructs can result in
undefined behavior at run time:</p>
</div>
<div class="ulist">
<ul>
<li>
<p>Integer arithmetic, as described in <a href="#sect-Defensive_Coding-C-Arithmetic">[sect-Defensive_Coding-C-Arithmetic]</a>.</p>
</li>
<li>
<p>Pointer arithmetic, string subscripting and the
<code>substring</code> method on strings (the
<code>string</code> class in the
<code>glib-2.0</code> 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 <code>substring</code>) where the implementation
would have range information to check the validity of indexes.
See <a href="#sect-Defensive_Coding-C-Pointers">[sect-Defensive_Coding-C-Pointers]</a>.</p>
</li>
<li>
<p>Similarly, Vala only performs garbage collection (through
reference counting) for <code>GObject</code> 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 <a href="#sect-Defensive_Coding-C-Use-After-Free">[sect-Defensive_Coding-C-Use-After-Free]</a>).</p>
</li>
</ul>
</div>
</div>
</div>
</div>
<div id="bottom" class="text-muted py-3" >
<div class="foot">
<div class="container">
<div class="row footerlinks">
<div class="col-sm-3 col-xs-6 widget">
<h3 class="widget-title">About</h3>
<div class="widget-body">
<dl>
<dd><a href="https://fedoraproject.org/wiki/Overview">About Fedora</a></dd>
<dd><a href="https://getfedora.org/en/sponsors">Sponsors</a></dd>
<dd><a href="https://fedoramagazine.org">Fedora Magazine</a></dd>
<dd><a href="https://fedoraproject.org/wiki/Legal:Main#Legal">Legal</a></dd>
</dl>
<ul class="list-inline">
<li>
<a href="https://www.facebook.com/TheFedoraProject" class="btn-social btn-outline"><i class="fa fa-fw fa-facebook"></i></a>
</li>
<li>
<a href="https://plus.google.com/112917221531140868607" class="btn-social btn-outline"><i class="fa fa-fw fa-google-plus"></i></a>
</li>
<li>
<a href="https://twitter.com/fedora" class="btn-social btn-outline"><i class="fa fa-fw fa-twitter"></i></a>
</li>
</ul>
</div>
</div>
<div class="col-sm-3 col-xs-6 widget">
<h3 class="widget-title uppercase">Download</h3>
<div class="widget-body">
<dl>
<dd><a href="https://getfedora.org/en/workstation/download">Get Fedora Workstation</a></dd>
<dd><a href="https://getfedora.org/en/server/download">Get Fedora Server</a></dd>
<dd><a href="https://getfedora.org/en/atomic/download">Get Fedora Atomic</a></dd>
<dd><a href="https://spins.fedoraproject.org">Fedora Spins</a></dd>
<dd><a href="https://labs.fedoraproject.org">Fedora Labs</a></dd>
<dd><a href="https://arm.fedoraproject.org">Fedora ARM<span class="sup">&reg;</span></a></dd>
<dd><a href="https://alt.fedoraproject.org/">Alternative Downloads</a></dd>
</dl>
</div>
</div>
<div class="col-sm-3 col-xs-6 widget">
<h3 class="widget-title">Support</h3>
<div class="widget-body">
<dl>
<dd><a href="https://fedoraproject.org/wiki/Communicating_and_getting_help">Get Help</a></dd>
<dd><a href="https://ask.fedoraproject.org/">Ask Fedora</a></dd>
<dd><a href="https://fedoraproject.org/wiki/Common_F27_bugs">Common Bugs</a></dd>
<dd><a href="https://developer.fedoraproject.org/">Fedora Developer Portal</a></dd>
<dd><a href="https://docs.fedoraproject.org/f27/install-guide/index.html">Installation Guide</a></dd>
</dl>
</div>
</div>
<div class="col-sm-3 col-xs-6 widget">
<h3 class="widget-title">Join</h3>
<div class="widget-body">
<dl>
<dd><a href="https://fedoraproject.org/wiki/Join">Join Fedora</a></dd>
<dd><a href="http://fedoraplanet.org">Planet Fedora</a></dd>
<dd><a href="https://fedoraproject.org/wiki/SIGs">Fedora SIGs</a></dd>
<dd><a href="https://admin.fedoraproject.org/accounts/">Fedora Account System</a></dd>
<dd><a href="https://fedoracommunity.org/">Fedora Community</a></dd>
</dl>
</div>
</div>
</div> <!-- /row of widgets -->
<div class="row">
<div class="col-md-2">
<div class="widget-body">
<a href="https://www.redhat.com/"><img class="rh-logo" src="../../../master/_images/redhat-logo.png" alt="Red Hat Logo" /></a>
</div>
</div>
<div class="col-md-7">
<div class="widget-body">
<p class="sponsor">Fedora is sponsored by Red Hat.</p>
<p class="sponsor"><a href="https://www.redhat.com/en/technologies/linux-platforms/articles/relationship-between-fedora-and-rhel">Learn more about the relationship between Red Hat and Fedora &raquo;</a></p>
<p class="copy">&copy; 2017 Red Hat, Inc. and others. Please send any comments or corrections to the <a href="https://pagure.io/fedora-docs/docs-fp-o">documentation team</a></p>
</div>
</div>
</div> <!-- /row of widgets -->
</div>
</div>
</div>
<!-- jQuery (necessary for Bootstrap's JavaScript plugins) -->
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>
<!-- Latest compiled and minified JavaScript -->
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/js/bootstrap.min.js"></script>
<script src="../../../master/_javascripts/bootstrap-offcanvas.js" type="text/javascript"></script>
<script type="text/javascript">
/*<![CDATA[*/
$(document).ready(function() {
$("[id^='topicGroup']").on('show.bs.collapse', function (event) {
if (!($(event.target).attr('id').match(/^topicSubGroup/))) {
$(this).parent().find("[id^='tgSpan']").toggleClass("fa-angle-right fa-angle-down");
}
});
$("[id^='topicGroup']").on('hide.bs.collapse', function (event) {
if (!($(event.target).attr('id').match(/^topicSubGroup/))) {
$(this).parent().find("[id^='tgSpan']").toggleClass("fa-angle-right fa-angle-down");
}
});
$("[id^='topicSubGroup']").on('show.bs.collapse', function () {
$(this).parent().find("[id^='sgSpan']").toggleClass("fa-caret-right fa-caret-down");
});
$("[id^='topicSubGroup']").on('hide.bs.collapse', function () {
$(this).parent().find("[id^='sgSpan']").toggleClass("fa-caret-right fa-caret-down");
});
});
/*]]>*/
</script>
</body>
</html>

View file

@ -1,428 +0,0 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta content="IE=edge" http-equiv="X-UA-Compatible">
<meta content="width=device-width, initial-scale=1.0" name="viewport">
<title>Defensive Coding Guide | Defensive Coding Guide | Specific Programming Tasks | Cryptography</title>
<!-- Bootstrap -->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css">
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap-theme.min.css">
<!-- Overpass Font -->
<link rel="stylesheet" href="https://overpass-30e2.kxcdn.com/overpass.css">
<link href="../../../master/_stylesheets/asciibinder.css" rel="stylesheet" />
<!-- HTML5 shim and Respond.js for IE8 support of HTML5 elements and media queries -->
<!-- WARNING: Respond.js doesn't work if you view the page via file:// -->
<!--[if lt IE 9]>
<script src="https://oss.maxcdn.com/html5shiv/3.7.2/html5shiv.min.js"></script>
<script src="https://oss.maxcdn.com/respond/1.4.2/respond.min.js"></script>
<![endif]-->
<link href="../../../master/_images/favicon32x32.png" rel="shortcut icon" type="text/css">
<!--[if IE]><link rel="shortcut icon" href="../../../master/_images/favicon.ico"><![endif]-->
<meta content="AsciiBinder" name="application-name">
</head>
<body>
<div class="navbar navbar-default" role="navigation">
<div class="container-fluid">
<div class="navbar-header">
<a class="navbar-brand" href="https://docs.fedoraproject.org/"><img alt="Fedora Documentation" src="../../../master/_images/fedora.svg"></a>
</div>
</div>
</div>
<div class="container">
<p class="toggle-nav visible-xs pull-left">
<button class="btn btn-default btn-sm" type="button" data-toggle="offcanvas">Toggle nav</button>
</p>
<ol class="breadcrumb">
<li class="sitename">
<a href="../../../index.html">Home</a>
</li>
<li class="hidden-xs active">
<a href="../../en-US/index.html">Defensive Coding Guide </a>
</li>
<li class="hidden-xs active">
<a href="../../en-US/index.html">Defensive Coding Guide</a>
</li>
<li class="hidden-xs active"><a href="../../en-US/tasks/Tasks-Library_Design.html">Specific Programming Tasks</a></li>
<li class="hidden-xs active">
Cryptography
</li>
</ol>
<div class="row row-offcanvas row-offcanvas-left">
<div class="col-xs-8 col-sm-3 col-md-3 sidebar sidebar-offcanvas">
<ul class="nav nav-sidebar">
<li class="nav-header">
<a class="" href="#" data-toggle="collapse" data-target="#topicGroup0">
<span id="tgSpan0" class="fa fa-angle-down"></span>Defensive Coding Guide
</a>
<ul id="topicGroup0" class="collapse in list-unstyled">
<li><a class="" href="../../en-US/index.html">Book Information</a></li>
<li class="nav-header">
<a class="" href="#" data-toggle="collapse" data-target="#topicSubGroup-0-1">
<span id="sgSpan-0-1" class="fa fa-caret-right"></span>&nbsp;Programming Languages
</a>
<ul id="topicSubGroup-0-1" class="nav-tertiary list-unstyled collapse">
<li><a class="" href="../../en-US/programming-languages/C.html">The C Programming Language</a></li>
<li><a class="" href="../../en-US/programming-languages/CXX.html">The C++ Programming&nbsp;Language</a></li>
<li><a class="" href="../../en-US/programming-languages/Java.html">The Java Programming Language</a></li>
<li><a class="" href="../../en-US/programming-languages/Python.html">The Python Programming Language</a></li>
<li><a class="" href="../../en-US/programming-languages/Shell.html">Shell Programming and bash</a></li>
<li><a class="" href="../../en-US/programming-languages/Go.html">The Go Programming Language</a></li>
<li><a class="" href="../../en-US/programming-languages/Vala.html">The Vala Programming Language</a></li>
</ul>
</li>
<li class="nav-header">
<a class="" href="#" data-toggle="collapse" data-target="#topicSubGroup-0-2">
<span id="sgSpan-0-2" class="fa fa-caret-down"></span>&nbsp;Specific Programming Tasks
</a>
<ul id="topicSubGroup-0-2" class="nav-tertiary list-unstyled collapse in">
<li><a class="" href="../../en-US/tasks/Tasks-Library_Design.html">Library Design</a></li>
<li><a class="" href="../../en-US/tasks/Tasks-Descriptors.html">File Descriptor Management</a></li>
<li><a class="" href="../../en-US/tasks/Tasks-File_System.html">File System Manipulation</a></li>
<li><a class="" href="../../en-US/tasks/Tasks-Temporary_Files.html">Temporary Files</a></li>
<li><a class="" href="../../en-US/tasks/Tasks-Processes.html">Processes</a></li>
<li><a class="" href="../../en-US/tasks/Tasks-Serialization.html">Serialization and Deserialization</a></li>
<li><a class=" active" href="../../en-US/tasks/Tasks-Cryptography.html">Cryptography</a></li>
<li><a class="" href="../../en-US/tasks/Tasks-Packaging.html">RPM Packaging</a></li>
</ul>
</li>
<li class="nav-header">
<a class="" href="#" data-toggle="collapse" data-target="#topicSubGroup-0-3">
<span id="sgSpan-0-3" class="fa fa-caret-right"></span>&nbsp;Implementing Security Features
</a>
<ul id="topicSubGroup-0-3" class="nav-tertiary list-unstyled collapse">
<li><a class="" href="../../en-US/features/Features-Authentication.html">Authentication and Authorization</a></li>
<li><a class="" href="../../en-US/features/Features-TLS.html">Transport Layer Security (TLS)</a></li>
<li><a class="" href="../../en-US/features/Features-HSM.html">Hardware Security Modules and Smart Cards</a></li>
</ul>
</li>
<li><a class="" href="../../en-US/Revision_History.html">Revision History</a></li>
</ul>
</li>
</ul>
</div>
<div class="col-xs-12 col-sm-9 col-md-9 main">
<div class="page-header">
<h2>Cryptography</h2>
</div>
<div class="sect1">
<h2 id="primitives"><a class="anchor" href="#primitives"></a>Primitives</h2>
<div class="sectionbody">
<div class="paragraph">
<p>Choosing from the following cryptographic primitives is
recommended:</p>
</div>
<div class="ulist">
<ul>
<li>
<p>RSA with 2048-bit keys and OAEP or PSS
padding</p>
</li>
<li>
<p>AES-128 in CBC mode</p>
</li>
<li>
<p>AES-128 in GCM mode</p>
</li>
<li>
<p>AES-256 in CBC mode</p>
</li>
<li>
<p>AES-256 in GCM mode</p>
</li>
<li>
<p>SHA-256</p>
</li>
<li>
<p>HMAC-SHA-256</p>
</li>
<li>
<p>HMAC-SHA-1</p>
</li>
</ul>
</div>
<div class="paragraph">
<p>Other cryptographic algorithms can be used if they are required
for interoperability with existing software:</p>
</div>
<div class="ulist">
<ul>
<li>
<p>RSA with key sizes larger than 1024
and legacy padding</p>
</li>
<li>
<p>AES-192</p>
</li>
<li>
<p>3DES (triple DES, with two or three 56-bit keys),
but strongly discouraged</p>
</li>
<li>
<p>RC4 (but very, very strongly discouraged)</p>
</li>
<li>
<p>SHA-1</p>
</li>
<li>
<p>HMAC-MD5</p>
</li>
</ul>
</div>
<div class="admonitionblock important">
<table>
<tr>
<td class="icon">
<i class="fa icon-important" title="Important"></i>
</td>
<td class="content">
<div class="title">Important</div>
<div class="paragraph">
<p>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 (<a href="#chap-Defensive_Coding-TLS">[chap-Defensive_Coding-TLS]</a>).</p>
</div>
<div class="paragraph">
<p>In particular, when using AES in CBC mode, it is necessary to
add integrity checking by other means, preferably using
HMAC-SHA-256 and <strong>after</strong> encryption (that
is, on the encrypted cipher text). For AES in GCM mode,
correct construction of nonces is absolutely essential.</p>
</div>
</td>
</tr>
</table>
</div>
</div>
</div>
<div class="sect1">
<h2 id="randomness"><a class="anchor" href="#randomness"></a>Randomness</h2>
<div class="sectionbody">
<div class="paragraph">
<p>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.</p>
</div>
<div class="ulist">
<ul>
<li>
<p><code>PK11_GenerateRandom</code> in the NSS library
(usable for high data rates)</p>
</li>
<li>
<p><code>RAND_bytes</code> in the OpenSSL library
(usable for high data rates)</p>
</li>
<li>
<p><code>gnutls_rnd</code> in GNUTLS, with
<code>GNUTLS_RND_RANDOM</code> as the first argument
(usable for high data rates)</p>
</li>
<li>
<p><code>java.security.SecureRandom</code> in Java
(usable for high data rates)</p>
</li>
<li>
<p><code>os.urandom</code> in Python</p>
</li>
<li>
<p>The <code>getrandom</code> system call since glibc 2.25</p>
</li>
<li>
<p>The <code>getentropy</code> call since glibc 2.25</p>
</li>
<li>
<p>Reading from the <code>/dev/urandom</code>
character device</p>
</li>
</ul>
</div>
<div class="paragraph">
<p>All these functions should be non-blocking, and they should not
wait until physical randomness becomes available. (Some
cryptography providers for Java can cause
<code>java.security.SecureRandom</code> to block, however.)
Those functions which do not obtain all bits directly from
<code>/dev/urandom</code> are suitable for high data
rates because they do not deplete the system-wide entropy pool.</p>
</div>
<div class="admonitionblock important">
<table>
<tr>
<td class="icon">
<i class="fa icon-important" title="Important"></i>
</td>
<td class="content">
<div class="title">Difficult to use API</div>
<div class="paragraph">
<p>Both <code>RAND_bytes</code> and
<code>PK11_GenerateRandom</code> have three-state
return values (with conflicting meanings). Careful error
checking is required. Please review the documentation when
using these functions.</p>
</div>
</td>
</tr>
</table>
</div>
<div class="admonitionblock important">
<table>
<tr>
<td class="icon">
<i class="fa icon-important" title="Important"></i>
</td>
<td class="content">
<div class="title">Difficult to use API</div>
<div class="paragraph">
<p>The <code>getrandom</code> system call has three-state
return values, hence requires careful error checking.</p>
</div>
<div class="paragraph">
<p>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 <code>syscall(SYS_getrandom, (void*)dest, (size_t)size, (unsigned int)0)</code>.
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.</p>
</div>
</td>
</tr>
</table>
</div>
<div class="paragraph">
<p>Other sources of randomness should be considered predictable.</p>
</div>
<div class="paragraph">
<p>Generating randomness for cryptographic keys in long-term use
may need different steps and is best left to cryptographic
libraries.</p>
</div>
</div>
</div>
</div>
</div>
</div>
<div id="bottom" class="text-muted py-3" >
<div class="foot">
<div class="container">
<div class="row footerlinks">
<div class="col-sm-3 col-xs-6 widget">
<h3 class="widget-title">About</h3>
<div class="widget-body">
<dl>
<dd><a href="https://fedoraproject.org/wiki/Overview">About Fedora</a></dd>
<dd><a href="https://getfedora.org/en/sponsors">Sponsors</a></dd>
<dd><a href="https://fedoramagazine.org">Fedora Magazine</a></dd>
<dd><a href="https://fedoraproject.org/wiki/Legal:Main#Legal">Legal</a></dd>
</dl>
<ul class="list-inline">
<li>
<a href="https://www.facebook.com/TheFedoraProject" class="btn-social btn-outline"><i class="fa fa-fw fa-facebook"></i></a>
</li>
<li>
<a href="https://plus.google.com/112917221531140868607" class="btn-social btn-outline"><i class="fa fa-fw fa-google-plus"></i></a>
</li>
<li>
<a href="https://twitter.com/fedora" class="btn-social btn-outline"><i class="fa fa-fw fa-twitter"></i></a>
</li>
</ul>
</div>
</div>
<div class="col-sm-3 col-xs-6 widget">
<h3 class="widget-title uppercase">Download</h3>
<div class="widget-body">
<dl>
<dd><a href="https://getfedora.org/en/workstation/download">Get Fedora Workstation</a></dd>
<dd><a href="https://getfedora.org/en/server/download">Get Fedora Server</a></dd>
<dd><a href="https://getfedora.org/en/atomic/download">Get Fedora Atomic</a></dd>
<dd><a href="https://spins.fedoraproject.org">Fedora Spins</a></dd>
<dd><a href="https://labs.fedoraproject.org">Fedora Labs</a></dd>
<dd><a href="https://arm.fedoraproject.org">Fedora ARM<span class="sup">&reg;</span></a></dd>
<dd><a href="https://alt.fedoraproject.org/">Alternative Downloads</a></dd>
</dl>
</div>
</div>
<div class="col-sm-3 col-xs-6 widget">
<h3 class="widget-title">Support</h3>
<div class="widget-body">
<dl>
<dd><a href="https://fedoraproject.org/wiki/Communicating_and_getting_help">Get Help</a></dd>
<dd><a href="https://ask.fedoraproject.org/">Ask Fedora</a></dd>
<dd><a href="https://fedoraproject.org/wiki/Common_F27_bugs">Common Bugs</a></dd>
<dd><a href="https://developer.fedoraproject.org/">Fedora Developer Portal</a></dd>
<dd><a href="https://docs.fedoraproject.org/f27/install-guide/index.html">Installation Guide</a></dd>
</dl>
</div>
</div>
<div class="col-sm-3 col-xs-6 widget">
<h3 class="widget-title">Join</h3>
<div class="widget-body">
<dl>
<dd><a href="https://fedoraproject.org/wiki/Join">Join Fedora</a></dd>
<dd><a href="http://fedoraplanet.org">Planet Fedora</a></dd>
<dd><a href="https://fedoraproject.org/wiki/SIGs">Fedora SIGs</a></dd>
<dd><a href="https://admin.fedoraproject.org/accounts/">Fedora Account System</a></dd>
<dd><a href="https://fedoracommunity.org/">Fedora Community</a></dd>
</dl>
</div>
</div>
</div> <!-- /row of widgets -->
<div class="row">
<div class="col-md-2">
<div class="widget-body">
<a href="https://www.redhat.com/"><img class="rh-logo" src="../../../master/_images/redhat-logo.png" alt="Red Hat Logo" /></a>
</div>
</div>
<div class="col-md-7">
<div class="widget-body">
<p class="sponsor">Fedora is sponsored by Red Hat.</p>
<p class="sponsor"><a href="https://www.redhat.com/en/technologies/linux-platforms/articles/relationship-between-fedora-and-rhel">Learn more about the relationship between Red Hat and Fedora &raquo;</a></p>
<p class="copy">&copy; 2017 Red Hat, Inc. and others. Please send any comments or corrections to the <a href="https://pagure.io/fedora-docs/docs-fp-o">documentation team</a></p>
</div>
</div>
</div> <!-- /row of widgets -->
</div>
</div>
</div>
<!-- jQuery (necessary for Bootstrap's JavaScript plugins) -->
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>
<!-- Latest compiled and minified JavaScript -->
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/js/bootstrap.min.js"></script>
<script src="../../../master/_javascripts/bootstrap-offcanvas.js" type="text/javascript"></script>
<script type="text/javascript">
/*<![CDATA[*/
$(document).ready(function() {
$("[id^='topicGroup']").on('show.bs.collapse', function (event) {
if (!($(event.target).attr('id').match(/^topicSubGroup/))) {
$(this).parent().find("[id^='tgSpan']").toggleClass("fa-angle-right fa-angle-down");
}
});
$("[id^='topicGroup']").on('hide.bs.collapse', function (event) {
if (!($(event.target).attr('id').match(/^topicSubGroup/))) {
$(this).parent().find("[id^='tgSpan']").toggleClass("fa-angle-right fa-angle-down");
}
});
$("[id^='topicSubGroup']").on('show.bs.collapse', function () {
$(this).parent().find("[id^='sgSpan']").toggleClass("fa-caret-right fa-caret-down");
});
$("[id^='topicSubGroup']").on('hide.bs.collapse', function () {
$(this).parent().find("[id^='sgSpan']").toggleClass("fa-caret-right fa-caret-down");
});
});
/*]]>*/
</script>
</body>
</html>

View file

@ -1,497 +0,0 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta content="IE=edge" http-equiv="X-UA-Compatible">
<meta content="width=device-width, initial-scale=1.0" name="viewport">
<title>Defensive Coding Guide | Defensive Coding Guide | Specific Programming Tasks | File Descriptor Management</title>
<!-- Bootstrap -->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css">
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap-theme.min.css">
<!-- Overpass Font -->
<link rel="stylesheet" href="https://overpass-30e2.kxcdn.com/overpass.css">
<link href="../../../master/_stylesheets/asciibinder.css" rel="stylesheet" />
<!-- HTML5 shim and Respond.js for IE8 support of HTML5 elements and media queries -->
<!-- WARNING: Respond.js doesn't work if you view the page via file:// -->
<!--[if lt IE 9]>
<script src="https://oss.maxcdn.com/html5shiv/3.7.2/html5shiv.min.js"></script>
<script src="https://oss.maxcdn.com/respond/1.4.2/respond.min.js"></script>
<![endif]-->
<link href="../../../master/_images/favicon32x32.png" rel="shortcut icon" type="text/css">
<!--[if IE]><link rel="shortcut icon" href="../../../master/_images/favicon.ico"><![endif]-->
<meta content="AsciiBinder" name="application-name">
</head>
<body>
<div class="navbar navbar-default" role="navigation">
<div class="container-fluid">
<div class="navbar-header">
<a class="navbar-brand" href="https://docs.fedoraproject.org/"><img alt="Fedora Documentation" src="../../../master/_images/fedora.svg"></a>
</div>
</div>
</div>
<div class="container">
<p class="toggle-nav visible-xs pull-left">
<button class="btn btn-default btn-sm" type="button" data-toggle="offcanvas">Toggle nav</button>
</p>
<ol class="breadcrumb">
<li class="sitename">
<a href="../../../index.html">Home</a>
</li>
<li class="hidden-xs active">
<a href="../../en-US/index.html">Defensive Coding Guide </a>
</li>
<li class="hidden-xs active">
<a href="../../en-US/index.html">Defensive Coding Guide</a>
</li>
<li class="hidden-xs active"><a href="../../en-US/tasks/Tasks-Library_Design.html">Specific Programming Tasks</a></li>
<li class="hidden-xs active">
File Descriptor Management
</li>
</ol>
<div class="row row-offcanvas row-offcanvas-left">
<div class="col-xs-8 col-sm-3 col-md-3 sidebar sidebar-offcanvas">
<ul class="nav nav-sidebar">
<li class="nav-header">
<a class="" href="#" data-toggle="collapse" data-target="#topicGroup0">
<span id="tgSpan0" class="fa fa-angle-down"></span>Defensive Coding Guide
</a>
<ul id="topicGroup0" class="collapse in list-unstyled">
<li><a class="" href="../../en-US/index.html">Book Information</a></li>
<li class="nav-header">
<a class="" href="#" data-toggle="collapse" data-target="#topicSubGroup-0-1">
<span id="sgSpan-0-1" class="fa fa-caret-right"></span>&nbsp;Programming Languages
</a>
<ul id="topicSubGroup-0-1" class="nav-tertiary list-unstyled collapse">
<li><a class="" href="../../en-US/programming-languages/C.html">The C Programming Language</a></li>
<li><a class="" href="../../en-US/programming-languages/CXX.html">The C++ Programming&nbsp;Language</a></li>
<li><a class="" href="../../en-US/programming-languages/Java.html">The Java Programming Language</a></li>
<li><a class="" href="../../en-US/programming-languages/Python.html">The Python Programming Language</a></li>
<li><a class="" href="../../en-US/programming-languages/Shell.html">Shell Programming and bash</a></li>
<li><a class="" href="../../en-US/programming-languages/Go.html">The Go Programming Language</a></li>
<li><a class="" href="../../en-US/programming-languages/Vala.html">The Vala Programming Language</a></li>
</ul>
</li>
<li class="nav-header">
<a class="" href="#" data-toggle="collapse" data-target="#topicSubGroup-0-2">
<span id="sgSpan-0-2" class="fa fa-caret-down"></span>&nbsp;Specific Programming Tasks
</a>
<ul id="topicSubGroup-0-2" class="nav-tertiary list-unstyled collapse in">
<li><a class="" href="../../en-US/tasks/Tasks-Library_Design.html">Library Design</a></li>
<li><a class=" active" href="../../en-US/tasks/Tasks-Descriptors.html">File Descriptor Management</a></li>
<li><a class="" href="../../en-US/tasks/Tasks-File_System.html">File System Manipulation</a></li>
<li><a class="" href="../../en-US/tasks/Tasks-Temporary_Files.html">Temporary Files</a></li>
<li><a class="" href="../../en-US/tasks/Tasks-Processes.html">Processes</a></li>
<li><a class="" href="../../en-US/tasks/Tasks-Serialization.html">Serialization and Deserialization</a></li>
<li><a class="" href="../../en-US/tasks/Tasks-Cryptography.html">Cryptography</a></li>
<li><a class="" href="../../en-US/tasks/Tasks-Packaging.html">RPM Packaging</a></li>
</ul>
</li>
<li class="nav-header">
<a class="" href="#" data-toggle="collapse" data-target="#topicSubGroup-0-3">
<span id="sgSpan-0-3" class="fa fa-caret-right"></span>&nbsp;Implementing Security Features
</a>
<ul id="topicSubGroup-0-3" class="nav-tertiary list-unstyled collapse">
<li><a class="" href="../../en-US/features/Features-Authentication.html">Authentication and Authorization</a></li>
<li><a class="" href="../../en-US/features/Features-TLS.html">Transport Layer Security (TLS)</a></li>
<li><a class="" href="../../en-US/features/Features-HSM.html">Hardware Security Modules and Smart Cards</a></li>
</ul>
</li>
<li><a class="" href="../../en-US/Revision_History.html">Revision History</a></li>
</ul>
</li>
</ul>
</div>
<div class="col-xs-12 col-sm-9 col-md-9 main">
<div class="page-header">
<h2>File Descriptor Management</h2>
</div>
<div id="preamble">
<div class="sectionbody">
<div class="paragraph">
<p>File descriptors underlie all input/output mechanisms offered by
the system. They are used to implementation the <code>FILE
*</code>-based functions found in
<code>&lt;stdio.h&gt;</code>, and all the file and network
communication facilities provided by the Python and Java
environments are eventually implemented in them.</p>
</div>
<div class="paragraph">
<p>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.</p>
</div>
</div>
</div>
<div class="sect1">
<h2 id="closing-descriptors"><a class="anchor" href="#closing-descriptors"></a>Closing Descriptors</h2>
<div class="sectionbody">
<div class="paragraph">
<p>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 <a href="#sect-Defensive_Coding-Tasks-Descriptors-Limit">Dealing with the <code>select</code> Limit</a>), 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.</p>
</div>
<div class="sect2">
<h3 id="error-handling-during-descriptor-close"><a class="anchor" href="#error-handling-during-descriptor-close"></a>Error Handling during Descriptor Close</h3>
<div class="paragraph">
<p>The <code>close</code> system call is always
successful in the sense that the passed file descriptor is
never valid after the function has been called. However,
<code>close</code> 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 <code>O_SYNC</code> or use
<code>fsync</code> or <code>fdatasync</code>, and
may also have to <code>fsync</code> the directory
containing the file.</p>
</div>
</div>
<div class="sect2">
<h3 id="closing-descriptors-and-race-conditions"><a class="anchor" href="#closing-descriptors-and-race-conditions"></a>Closing Descriptors and Race Conditions</h3>
<div class="paragraph">
<p>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.</p>
</div>
<div class="paragraph">
<p>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
<code>socketpair</code>, close one of the descriptors,
and call <code>shutdown(fd, SHUTRDWR)</code> on the
other.</p>
</div>
<div class="paragraph">
<p>When a descriptor is closed concurrently, the program does not
call <code>close</code> on the descriptor. Instead it
program uses <code>dup2</code> 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).</p>
</div>
<div class="paragraph">
<p>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.</p>
</div>
</div>
<div class="sect2">
<h3 id="lingering-state-after-close"><a class="anchor" href="#lingering-state-after-close"></a>Lingering State after Close</h3>
<div class="paragraph">
<p>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.</p>
</div>
<div class="paragraph">
<p>The <code>SO_LINGER</code> socket option alters the
behavior of <code>close</code>, 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 <code>close</code>
call, causing scalability issues.</p>
</div>
<div class="paragraph">
<p>Currently, there is no application-level countermeasure which
applies universally. Mitigation is possible with
<strong class="application">iptables</strong> (the
<code>connlimit</code> match type in particular) and
specialized filtering devices for denial-of-service network
traffic.</p>
</div>
<div class="paragraph">
<p>These problems are not related to the
<code>TIME_WAIT</code> state commonly seen in
<strong class="application">netstat</strong> output. The kernel
automatically expires such sockets if necessary.</p>
</div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="sect-Defensive_Coding-Tasks-Descriptors-Child_Processes"><a class="anchor" href="#sect-Defensive_Coding-Tasks-Descriptors-Child_Processes"></a>Preventing File Descriptor Leaks to Child Processes</h2>
<div class="sectionbody">
<div class="paragraph">
<p>Child processes created with <code>fork</code> 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 <code>execve</code>
(or any of the other functions such as <code>system</code>
or <code>posix_spawn</code>).</p>
</div>
<div class="paragraph">
<p>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:</p>
</div>
<div class="ulist">
<ul>
<li>
<p>Set the close-on-exec flag on all newly created file
descriptors. Traditionally, this flag is controlled by the
<code>FD_CLOEXEC</code> flag, using
<code>F_GETFD</code> and <code>F_SETFD</code>
operations of the <code>fcntl</code> function.</p>
<div class="paragraph">
<p>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
<code>FD_CLOEXEC</code> was set. Therefore, many system
calls which create descriptors (such as
<code>open</code> and <code>openat</code>)
now accept the <code>O_CLOEXEC</code> flag
(<code>SOCK_CLOEXEC</code> for
<code>socket</code> and
<code>socketpair</code>), which cause the
<code>FD_CLOEXEC</code> flag to be set for the file
descriptor in an atomic fashion. In addition, a few new
systems calls were introduced, such as
<code>pipe2</code> and <code>dup3</code>.</p>
</div>
<div class="paragraph">
<p>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.</p>
</div>
</li>
<li>
<p>After calling <code>fork</code>, but before creating
a new process image with <code>execve</code>, all
file descriptors which the child process will not need are
closed.</p>
<div class="paragraph">
<p>Traditionally, this was implemented as a loop over file
descriptors ranging from <code>3</code> to
<code>255</code> and later <code>1023</code>.
But this is only an approximation because it is possible to
create file descriptors outside this range easily (see <a href="#sect-Defensive_Coding-Tasks-Descriptors-Limit">Dealing with the <code>select</code> Limit</a>).
Another approach reads <code>/proc/self/fd</code>
and closes the unexpected descriptors listed there, but this
approach is much slower.</p>
</div>
</li>
</ul>
</div>
<div class="paragraph">
<p>At present, environments which care about file descriptor
leakage implement the second approach. OpenJDK 6 and 7
are among them.</p>
</div>
</div>
</div>
<div class="sect1">
<h2 id="sect-Defensive_Coding-Tasks-Descriptors-Limit"><a class="anchor" href="#sect-Defensive_Coding-Tasks-Descriptors-Limit"></a>Dealing with the <code>select</code> Limit</h2>
<div class="sectionbody">
<div class="paragraph">
<p>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.</p>
</div>
<div class="paragraph">
<p>The <code>select</code> function only supports a
maximum of <code>FD_SETSIZE</code> file descriptors
(that is, the maximum permitted value for a file descriptor
is <code>FD_SETSIZE - 1</code>, usually 1023.) If a
process opens many files, descriptors may exceed such
limits. It is impossible to query such descriptors using
<code>select</code>.</p>
</div>
<div class="paragraph">
<p>If a library which creates many file descriptors is used in
the same process as a library which uses
<code>select</code>, at least one of them needs to
be changed.
Calls to <code>select</code> can be replaced with
calls to <code>poll</code> or another event handling
mechanism. Replacing the <code>select</code> function
is the recommended approach.</p>
</div>
<div class="paragraph">
<p>Alternatively, the library with high descriptor usage can
relocate descriptors above the <code>FD_SETSIZE</code>
limit using the following procedure.</p>
</div>
<div class="ulist">
<ul>
<li>
<p>Create the file descriptor <code>fd</code> as
usual, preferably with the <code>O_CLOEXEC</code>
flag.</p>
</li>
<li>
<p>Before doing anything else with the descriptor
<code>fd</code>, invoke:</p>
</li>
</ul>
</div>
<div class="listingblock">
<div class="content">
<pre> int newfd = fcntl(fd, F_DUPFD_CLOEXEC, (long)FD_SETSIZE);</pre>
</div>
</div>
<div class="ulist">
<ul>
<li>
<p>Check that <code>newfd</code> result is
non-negative, otherwise close <code>fd</code> and
report an error, and return.</p>
</li>
<li>
<p>Close <code>fd</code> and continue to use
<code>newfd</code>.</p>
</li>
</ul>
</div>
<div class="paragraph">
<p>The new descriptor has been allocated above the
<code>FD_SETSIZE</code>. Even though this algorithm
is racy in the sense that the <code>FD_SETSIZE</code>
first descriptors could fill up, a very high degree of
physical parallelism is required before this becomes a problem.</p>
</div>
</div>
</div>
</div>
</div>
</div>
<div id="bottom" class="text-muted py-3" >
<div class="foot">
<div class="container">
<div class="row footerlinks">
<div class="col-sm-3 col-xs-6 widget">
<h3 class="widget-title">About</h3>
<div class="widget-body">
<dl>
<dd><a href="https://fedoraproject.org/wiki/Overview">About Fedora</a></dd>
<dd><a href="https://getfedora.org/en/sponsors">Sponsors</a></dd>
<dd><a href="https://fedoramagazine.org">Fedora Magazine</a></dd>
<dd><a href="https://fedoraproject.org/wiki/Legal:Main#Legal">Legal</a></dd>
</dl>
<ul class="list-inline">
<li>
<a href="https://www.facebook.com/TheFedoraProject" class="btn-social btn-outline"><i class="fa fa-fw fa-facebook"></i></a>
</li>
<li>
<a href="https://plus.google.com/112917221531140868607" class="btn-social btn-outline"><i class="fa fa-fw fa-google-plus"></i></a>
</li>
<li>
<a href="https://twitter.com/fedora" class="btn-social btn-outline"><i class="fa fa-fw fa-twitter"></i></a>
</li>
</ul>
</div>
</div>
<div class="col-sm-3 col-xs-6 widget">
<h3 class="widget-title uppercase">Download</h3>
<div class="widget-body">
<dl>
<dd><a href="https://getfedora.org/en/workstation/download">Get Fedora Workstation</a></dd>
<dd><a href="https://getfedora.org/en/server/download">Get Fedora Server</a></dd>
<dd><a href="https://getfedora.org/en/atomic/download">Get Fedora Atomic</a></dd>
<dd><a href="https://spins.fedoraproject.org">Fedora Spins</a></dd>
<dd><a href="https://labs.fedoraproject.org">Fedora Labs</a></dd>
<dd><a href="https://arm.fedoraproject.org">Fedora ARM<span class="sup">&reg;</span></a></dd>
<dd><a href="https://alt.fedoraproject.org/">Alternative Downloads</a></dd>
</dl>
</div>
</div>
<div class="col-sm-3 col-xs-6 widget">
<h3 class="widget-title">Support</h3>
<div class="widget-body">
<dl>
<dd><a href="https://fedoraproject.org/wiki/Communicating_and_getting_help">Get Help</a></dd>
<dd><a href="https://ask.fedoraproject.org/">Ask Fedora</a></dd>
<dd><a href="https://fedoraproject.org/wiki/Common_F27_bugs">Common Bugs</a></dd>
<dd><a href="https://developer.fedoraproject.org/">Fedora Developer Portal</a></dd>
<dd><a href="https://docs.fedoraproject.org/f27/install-guide/index.html">Installation Guide</a></dd>
</dl>
</div>
</div>
<div class="col-sm-3 col-xs-6 widget">
<h3 class="widget-title">Join</h3>
<div class="widget-body">
<dl>
<dd><a href="https://fedoraproject.org/wiki/Join">Join Fedora</a></dd>
<dd><a href="http://fedoraplanet.org">Planet Fedora</a></dd>
<dd><a href="https://fedoraproject.org/wiki/SIGs">Fedora SIGs</a></dd>
<dd><a href="https://admin.fedoraproject.org/accounts/">Fedora Account System</a></dd>
<dd><a href="https://fedoracommunity.org/">Fedora Community</a></dd>
</dl>
</div>
</div>
</div> <!-- /row of widgets -->
<div class="row">
<div class="col-md-2">
<div class="widget-body">
<a href="https://www.redhat.com/"><img class="rh-logo" src="../../../master/_images/redhat-logo.png" alt="Red Hat Logo" /></a>
</div>
</div>
<div class="col-md-7">
<div class="widget-body">
<p class="sponsor">Fedora is sponsored by Red Hat.</p>
<p class="sponsor"><a href="https://www.redhat.com/en/technologies/linux-platforms/articles/relationship-between-fedora-and-rhel">Learn more about the relationship between Red Hat and Fedora &raquo;</a></p>
<p class="copy">&copy; 2017 Red Hat, Inc. and others. Please send any comments or corrections to the <a href="https://pagure.io/fedora-docs/docs-fp-o">documentation team</a></p>
</div>
</div>
</div> <!-- /row of widgets -->
</div>
</div>
</div>
<!-- jQuery (necessary for Bootstrap's JavaScript plugins) -->
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>
<!-- Latest compiled and minified JavaScript -->
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/js/bootstrap.min.js"></script>
<script src="../../../master/_javascripts/bootstrap-offcanvas.js" type="text/javascript"></script>
<script type="text/javascript">
/*<![CDATA[*/
$(document).ready(function() {
$("[id^='topicGroup']").on('show.bs.collapse', function (event) {
if (!($(event.target).attr('id').match(/^topicSubGroup/))) {
$(this).parent().find("[id^='tgSpan']").toggleClass("fa-angle-right fa-angle-down");
}
});
$("[id^='topicGroup']").on('hide.bs.collapse', function (event) {
if (!($(event.target).attr('id').match(/^topicSubGroup/))) {
$(this).parent().find("[id^='tgSpan']").toggleClass("fa-angle-right fa-angle-down");
}
});
$("[id^='topicSubGroup']").on('show.bs.collapse', function () {
$(this).parent().find("[id^='sgSpan']").toggleClass("fa-caret-right fa-caret-down");
});
$("[id^='topicSubGroup']").on('hide.bs.collapse', function () {
$(this).parent().find("[id^='sgSpan']").toggleClass("fa-caret-right fa-caret-down");
});
});
/*]]>*/
</script>
</body>
</html>

View file

@ -1,548 +0,0 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta content="IE=edge" http-equiv="X-UA-Compatible">
<meta content="width=device-width, initial-scale=1.0" name="viewport">
<title>Defensive Coding Guide | Defensive Coding Guide | Specific Programming Tasks | File System Manipulation</title>
<!-- Bootstrap -->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css">
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap-theme.min.css">
<!-- Overpass Font -->
<link rel="stylesheet" href="https://overpass-30e2.kxcdn.com/overpass.css">
<link href="../../../master/_stylesheets/asciibinder.css" rel="stylesheet" />
<!-- HTML5 shim and Respond.js for IE8 support of HTML5 elements and media queries -->
<!-- WARNING: Respond.js doesn't work if you view the page via file:// -->
<!--[if lt IE 9]>
<script src="https://oss.maxcdn.com/html5shiv/3.7.2/html5shiv.min.js"></script>
<script src="https://oss.maxcdn.com/respond/1.4.2/respond.min.js"></script>
<![endif]-->
<link href="../../../master/_images/favicon32x32.png" rel="shortcut icon" type="text/css">
<!--[if IE]><link rel="shortcut icon" href="../../../master/_images/favicon.ico"><![endif]-->
<meta content="AsciiBinder" name="application-name">
</head>
<body>
<div class="navbar navbar-default" role="navigation">
<div class="container-fluid">
<div class="navbar-header">
<a class="navbar-brand" href="https://docs.fedoraproject.org/"><img alt="Fedora Documentation" src="../../../master/_images/fedora.svg"></a>
</div>
</div>
</div>
<div class="container">
<p class="toggle-nav visible-xs pull-left">
<button class="btn btn-default btn-sm" type="button" data-toggle="offcanvas">Toggle nav</button>
</p>
<ol class="breadcrumb">
<li class="sitename">
<a href="../../../index.html">Home</a>
</li>
<li class="hidden-xs active">
<a href="../../en-US/index.html">Defensive Coding Guide </a>
</li>
<li class="hidden-xs active">
<a href="../../en-US/index.html">Defensive Coding Guide</a>
</li>
<li class="hidden-xs active"><a href="../../en-US/tasks/Tasks-Library_Design.html">Specific Programming Tasks</a></li>
<li class="hidden-xs active">
File System Manipulation
</li>
</ol>
<div class="row row-offcanvas row-offcanvas-left">
<div class="col-xs-8 col-sm-3 col-md-3 sidebar sidebar-offcanvas">
<ul class="nav nav-sidebar">
<li class="nav-header">
<a class="" href="#" data-toggle="collapse" data-target="#topicGroup0">
<span id="tgSpan0" class="fa fa-angle-down"></span>Defensive Coding Guide
</a>
<ul id="topicGroup0" class="collapse in list-unstyled">
<li><a class="" href="../../en-US/index.html">Book Information</a></li>
<li class="nav-header">
<a class="" href="#" data-toggle="collapse" data-target="#topicSubGroup-0-1">
<span id="sgSpan-0-1" class="fa fa-caret-right"></span>&nbsp;Programming Languages
</a>
<ul id="topicSubGroup-0-1" class="nav-tertiary list-unstyled collapse">
<li><a class="" href="../../en-US/programming-languages/C.html">The C Programming Language</a></li>
<li><a class="" href="../../en-US/programming-languages/CXX.html">The C++ Programming&nbsp;Language</a></li>
<li><a class="" href="../../en-US/programming-languages/Java.html">The Java Programming Language</a></li>
<li><a class="" href="../../en-US/programming-languages/Python.html">The Python Programming Language</a></li>
<li><a class="" href="../../en-US/programming-languages/Shell.html">Shell Programming and bash</a></li>
<li><a class="" href="../../en-US/programming-languages/Go.html">The Go Programming Language</a></li>
<li><a class="" href="../../en-US/programming-languages/Vala.html">The Vala Programming Language</a></li>
</ul>
</li>
<li class="nav-header">
<a class="" href="#" data-toggle="collapse" data-target="#topicSubGroup-0-2">
<span id="sgSpan-0-2" class="fa fa-caret-down"></span>&nbsp;Specific Programming Tasks
</a>
<ul id="topicSubGroup-0-2" class="nav-tertiary list-unstyled collapse in">
<li><a class="" href="../../en-US/tasks/Tasks-Library_Design.html">Library Design</a></li>
<li><a class="" href="../../en-US/tasks/Tasks-Descriptors.html">File Descriptor Management</a></li>
<li><a class=" active" href="../../en-US/tasks/Tasks-File_System.html">File System Manipulation</a></li>
<li><a class="" href="../../en-US/tasks/Tasks-Temporary_Files.html">Temporary Files</a></li>
<li><a class="" href="../../en-US/tasks/Tasks-Processes.html">Processes</a></li>
<li><a class="" href="../../en-US/tasks/Tasks-Serialization.html">Serialization and Deserialization</a></li>
<li><a class="" href="../../en-US/tasks/Tasks-Cryptography.html">Cryptography</a></li>
<li><a class="" href="../../en-US/tasks/Tasks-Packaging.html">RPM Packaging</a></li>
</ul>
</li>
<li class="nav-header">
<a class="" href="#" data-toggle="collapse" data-target="#topicSubGroup-0-3">
<span id="sgSpan-0-3" class="fa fa-caret-right"></span>&nbsp;Implementing Security Features
</a>
<ul id="topicSubGroup-0-3" class="nav-tertiary list-unstyled collapse">
<li><a class="" href="../../en-US/features/Features-Authentication.html">Authentication and Authorization</a></li>
<li><a class="" href="../../en-US/features/Features-TLS.html">Transport Layer Security (TLS)</a></li>
<li><a class="" href="../../en-US/features/Features-HSM.html">Hardware Security Modules and Smart Cards</a></li>
</ul>
</li>
<li><a class="" href="../../en-US/Revision_History.html">Revision History</a></li>
</ul>
</li>
</ul>
</div>
<div class="col-xs-12 col-sm-9 col-md-9 main">
<div class="page-header">
<h2>File System Manipulation</h2>
</div>
<div id="preamble">
<div class="sectionbody">
<div class="paragraph">
<p>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.</p>
</div>
<div class="paragraph">
<p>Temporary files are covered in their own chapter, <a href="#chap-Defensive_Coding-Tasks-Temporary_Files">[chap-Defensive_Coding-Tasks-Temporary_Files]</a>.</p>
</div>
</div>
</div>
<div class="sect1">
<h2 id="sect-Defensive_Coding-Tasks-File_System-Unowned"><a class="anchor" href="#sect-Defensive_Coding-Tasks-File_System-Unowned"></a>Working with Files and Directories Owned by Other Users</h2>
<div class="sectionbody">
<div class="paragraph">
<p>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
<a href="#sect-Defensive_Coding-Tasks-File_System-Foreign">Accessing the File System as a Different User</a>.</p>
</div>
<div class="paragraph">
<p>Accessing files across trust boundaries faces several
challenges, particularly if an entire directory tree is being
traversed:</p>
</div>
<div class="olist arabic">
<ol class="arabic">
<li>
<p>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 <code>readdir</code>.</p>
</li>
<li>
<p>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 <code>O_NONBLOCK</code> flag is specified.</p>
</li>
<li>
<p>Hard links and symbolic links can redirect the effect of
file system operations in unexpected ways. The
<code>O_NOFOLLOW</code> and
<code>AT_SYMLINK_NOFOLLOW</code> variants of system
calls only affected final path name component.</p>
</li>
<li>
<p>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.</p>
</li>
</ol>
</div>
<div class="paragraph">
<p>Files should always be created with the
<code>O_CREAT</code> and <code>O_EXCL</code> 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 <code>000</code> if
possible, and adjust it afterwards with
<code>fchmod</code>.</p>
</div>
<div class="paragraph">
<p>To avoid issues related to symbolic links and directory tree
restructuring, the “<code>at</code>” variants of system
calls have to be used (that is, functions like
<code>openat</code>, <code>fchownat</code>,
<code>fchmodat</code>, and
<code>unlinkat</code>, together with
<code>O_NOFOLLOW</code> or
<code>AT_SYMLINK_NOFOLLOW</code>). 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
<code>opendirat</code> function can be emulated with
<code>openat</code> (with an
<code>O_DIRECTORY</code> flag, to avoid opening special
files with side effects), followed by
<code>fdopendir</code>.</p>
</div>
<div class="paragraph">
<p>If the “<code>at</code>” 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.)
<code>fchdir</code> 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 “<code>at</code>”-based
approach. <code>chdir("&#8230;&#8203;")</code> is unsafe because it
might ascend outside the intended directory tree.</p>
</div>
<div class="paragraph">
<p>This “<code>at</code>” function emulation is currently
required when manipulating extended attributes. In this case,
the <code>lsetxattr</code> function can be used, with a
relative path name consisting of a single component. This also
applies to SELinux contexts and the
<code>lsetfilecon</code> function.</p>
</div>
<div class="paragraph">
<p>Currently, it is not possible to avoid opening special files
<strong>and</strong> 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.)
<code>fchmodat</code> and <code>fchownat</code>
affect files whose link count is greater than one. But opening
the files, checking that the link count is one with
<code>fstat</code>, and using
<code>fchmod</code> and <code>fchown</code> 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.</p>
</div>
<div class="paragraph">
<p>Similarly, when just reading a directory owned by an untrusted
user, it is currently impossible to reliably avoid opening
special files.</p>
</div>
<div class="paragraph">
<p>There is no workaround against the instability of the file list
returned by <code>readdir</code>. Concurrent
modification of the directory can result in a list of files
being returned which never actually existed on disk.</p>
</div>
<div class="paragraph">
<p>Hard links and symbolic links can be safely deleted using
<code>unlinkat</code> without further checks because
deletion only affects the name within the directory tree being
processed.</p>
</div>
</div>
</div>
<div class="sect1">
<h2 id="sect-Defensive_Coding-Tasks-File_System-Foreign"><a class="anchor" href="#sect-Defensive_Coding-Tasks-File_System-Foreign"></a>Accessing the File System as a Different User</h2>
<div class="sectionbody">
<div class="paragraph">
<p>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 <a href="#sect-Defensive_Coding-Tasks-File_System-Foreign">Accessing the File System as a Different User</a>.</p>
</div>
<div class="paragraph">
<p>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 <code>stat</code> system call.</p>
</div>
<div class="paragraph">
<p>An existing process could change its user and group ID using
<code>setfsuid</code> and <code>setfsgid</code>.
(These functions are preferred over <code>seteuid</code>
and <code>setegid</code> 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.</p>
</div>
<div class="paragraph">
<p>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.</p>
</div>
</div>
</div>
<div class="sect1">
<h2 id="sect-Defensive_Coding-Tasks-File_System-Limits"><a class="anchor" href="#sect-Defensive_Coding-Tasks-File_System-Limits"></a>File System Limits</h2>
<div class="sectionbody">
<div class="paragraph">
<p>For historical reasons, there are preprocessor constants such as
<code>PATH_MAX</code>, <code>NAME_MAX</code>.
However, on most systems, the length of canonical path names
(absolute path names with all symbolic links resolved, as
returned by <code>realpath</code> or
<code>canonicalize_file_name</code>) can exceed
<code>PATH_MAX</code> bytes, and individual file name
components can be longer than <code>NAME_MAX</code>. This
is also true of the <code>_PC_PATH_MAX</code> and
<code>_PC_NAME_MAX</code> values returned by
<code>pathconf</code>, and the
<code>f_namemax</code> member of <code>struct
statvfs</code>. Therefore, these constants should not be
used. This is also reason why the
<code>readdir_r</code> should never be used (instead,
use <code>readdir</code>).</p>
</div>
<div class="paragraph">
<p>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.</p>
</div>
</div>
</div>
<div class="sect1">
<h2 id="sect-Defensive_Coding-Tasks-File_System-Features"><a class="anchor" href="#sect-Defensive_Coding-Tasks-File_System-Features"></a>File system features</h2>
<div class="sectionbody">
<div class="paragraph">
<p>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.</p>
</div>
<div class="ulist">
<ul>
<li>
<p>Some file systems are case-insensitive. Most should be
case-preserving, though.</p>
</li>
<li>
<p>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.</p>
</li>
<li>
<p>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
<code>readdir</code> might still result in a
different byte sequence.</p>
</li>
<li>
<p>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.</p>
</li>
<li>
<p>Non-regular files (device nodes, FIFOs) are not generally
available.</p>
</li>
<li>
<p>Only on some file systems, files can have holes, that is,
not all of their contents is backed by disk storage.</p>
</li>
<li>
<p><code>ioctl</code> support (even fairly generic
functionality such as <code>FIEMAP</code> for
discovering physical file layout and holes) is
file-system-specific.</p>
</li>
<li>
<p>Not all file systems support extended attributes, ACLs and
SELinux metadata. Size and naming restriction on extended
attributes vary.</p>
</li>
<li>
<p>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.</p>
</li>
<li>
<p>Renaming (or moving) files using <code>rename</code>
can fail (even when <code>stat</code> 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.</p>
</li>
<li>
<p>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.</p>
</li>
<li>
<p>Resolution of time stamps varies from two seconds to
nanoseconds. Not all time stamps are available on all file
systems. File creation time (<strong>birth
time</strong>) is not exposed over the
<code>stat</code>/<code>fstat</code>
interface, even if stored by the file system.</p>
</li>
</ul>
</div>
</div>
</div>
<div class="sect1">
<h2 id="sect-Defensive_Coding-Tasks-File_System-Free_Space"><a class="anchor" href="#sect-Defensive_Coding-Tasks-File_System-Free_Space"></a>Checking Free Space</h2>
<div class="sectionbody">
<div class="paragraph">
<p>The <code>statvfs</code> and
<code>fstatvfs</code> functions allow programs to
examine the number of available blocks and inodes, through the
members <code>f_bfree</code>, <code>f_bavail</code>,
<code>f_ffree</code>, and <code>f_favail</code> of
<code>struct statvfs</code>. Some file systems return
fictional values in the <code>f_ffree</code> and
<code>f_favail</code> 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 <code>f_bfree</code> field should be
reasonably accurate, though.</p>
</div>
</div>
</div>
</div>
</div>
</div>
<div id="bottom" class="text-muted py-3" >
<div class="foot">
<div class="container">
<div class="row footerlinks">
<div class="col-sm-3 col-xs-6 widget">
<h3 class="widget-title">About</h3>
<div class="widget-body">
<dl>
<dd><a href="https://fedoraproject.org/wiki/Overview">About Fedora</a></dd>
<dd><a href="https://getfedora.org/en/sponsors">Sponsors</a></dd>
<dd><a href="https://fedoramagazine.org">Fedora Magazine</a></dd>
<dd><a href="https://fedoraproject.org/wiki/Legal:Main#Legal">Legal</a></dd>
</dl>
<ul class="list-inline">
<li>
<a href="https://www.facebook.com/TheFedoraProject" class="btn-social btn-outline"><i class="fa fa-fw fa-facebook"></i></a>
</li>
<li>
<a href="https://plus.google.com/112917221531140868607" class="btn-social btn-outline"><i class="fa fa-fw fa-google-plus"></i></a>
</li>
<li>
<a href="https://twitter.com/fedora" class="btn-social btn-outline"><i class="fa fa-fw fa-twitter"></i></a>
</li>
</ul>
</div>
</div>
<div class="col-sm-3 col-xs-6 widget">
<h3 class="widget-title uppercase">Download</h3>
<div class="widget-body">
<dl>
<dd><a href="https://getfedora.org/en/workstation/download">Get Fedora Workstation</a></dd>
<dd><a href="https://getfedora.org/en/server/download">Get Fedora Server</a></dd>
<dd><a href="https://getfedora.org/en/atomic/download">Get Fedora Atomic</a></dd>
<dd><a href="https://spins.fedoraproject.org">Fedora Spins</a></dd>
<dd><a href="https://labs.fedoraproject.org">Fedora Labs</a></dd>
<dd><a href="https://arm.fedoraproject.org">Fedora ARM<span class="sup">&reg;</span></a></dd>
<dd><a href="https://alt.fedoraproject.org/">Alternative Downloads</a></dd>
</dl>
</div>
</div>
<div class="col-sm-3 col-xs-6 widget">
<h3 class="widget-title">Support</h3>
<div class="widget-body">
<dl>
<dd><a href="https://fedoraproject.org/wiki/Communicating_and_getting_help">Get Help</a></dd>
<dd><a href="https://ask.fedoraproject.org/">Ask Fedora</a></dd>
<dd><a href="https://fedoraproject.org/wiki/Common_F27_bugs">Common Bugs</a></dd>
<dd><a href="https://developer.fedoraproject.org/">Fedora Developer Portal</a></dd>
<dd><a href="https://docs.fedoraproject.org/f27/install-guide/index.html">Installation Guide</a></dd>
</dl>
</div>
</div>
<div class="col-sm-3 col-xs-6 widget">
<h3 class="widget-title">Join</h3>
<div class="widget-body">
<dl>
<dd><a href="https://fedoraproject.org/wiki/Join">Join Fedora</a></dd>
<dd><a href="http://fedoraplanet.org">Planet Fedora</a></dd>
<dd><a href="https://fedoraproject.org/wiki/SIGs">Fedora SIGs</a></dd>
<dd><a href="https://admin.fedoraproject.org/accounts/">Fedora Account System</a></dd>
<dd><a href="https://fedoracommunity.org/">Fedora Community</a></dd>
</dl>
</div>
</div>
</div> <!-- /row of widgets -->
<div class="row">
<div class="col-md-2">
<div class="widget-body">
<a href="https://www.redhat.com/"><img class="rh-logo" src="../../../master/_images/redhat-logo.png" alt="Red Hat Logo" /></a>
</div>
</div>
<div class="col-md-7">
<div class="widget-body">
<p class="sponsor">Fedora is sponsored by Red Hat.</p>
<p class="sponsor"><a href="https://www.redhat.com/en/technologies/linux-platforms/articles/relationship-between-fedora-and-rhel">Learn more about the relationship between Red Hat and Fedora &raquo;</a></p>
<p class="copy">&copy; 2017 Red Hat, Inc. and others. Please send any comments or corrections to the <a href="https://pagure.io/fedora-docs/docs-fp-o">documentation team</a></p>
</div>
</div>
</div> <!-- /row of widgets -->
</div>
</div>
</div>
<!-- jQuery (necessary for Bootstrap's JavaScript plugins) -->
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>
<!-- Latest compiled and minified JavaScript -->
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/js/bootstrap.min.js"></script>
<script src="../../../master/_javascripts/bootstrap-offcanvas.js" type="text/javascript"></script>
<script type="text/javascript">
/*<![CDATA[*/
$(document).ready(function() {
$("[id^='topicGroup']").on('show.bs.collapse', function (event) {
if (!($(event.target).attr('id').match(/^topicSubGroup/))) {
$(this).parent().find("[id^='tgSpan']").toggleClass("fa-angle-right fa-angle-down");
}
});
$("[id^='topicGroup']").on('hide.bs.collapse', function (event) {
if (!($(event.target).attr('id').match(/^topicSubGroup/))) {
$(this).parent().find("[id^='tgSpan']").toggleClass("fa-angle-right fa-angle-down");
}
});
$("[id^='topicSubGroup']").on('show.bs.collapse', function () {
$(this).parent().find("[id^='sgSpan']").toggleClass("fa-caret-right fa-caret-down");
});
$("[id^='topicSubGroup']").on('hide.bs.collapse', function () {
$(this).parent().find("[id^='sgSpan']").toggleClass("fa-caret-right fa-caret-down");
});
});
/*]]>*/
</script>
</body>
</html>

View file

@ -1,425 +0,0 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta content="IE=edge" http-equiv="X-UA-Compatible">
<meta content="width=device-width, initial-scale=1.0" name="viewport">
<title>Defensive Coding Guide | Defensive Coding Guide | Specific Programming Tasks | Library Design</title>
<!-- Bootstrap -->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css">
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap-theme.min.css">
<!-- Overpass Font -->
<link rel="stylesheet" href="https://overpass-30e2.kxcdn.com/overpass.css">
<link href="../../../master/_stylesheets/asciibinder.css" rel="stylesheet" />
<!-- HTML5 shim and Respond.js for IE8 support of HTML5 elements and media queries -->
<!-- WARNING: Respond.js doesn't work if you view the page via file:// -->
<!--[if lt IE 9]>
<script src="https://oss.maxcdn.com/html5shiv/3.7.2/html5shiv.min.js"></script>
<script src="https://oss.maxcdn.com/respond/1.4.2/respond.min.js"></script>
<![endif]-->
<link href="../../../master/_images/favicon32x32.png" rel="shortcut icon" type="text/css">
<!--[if IE]><link rel="shortcut icon" href="../../../master/_images/favicon.ico"><![endif]-->
<meta content="AsciiBinder" name="application-name">
</head>
<body>
<div class="navbar navbar-default" role="navigation">
<div class="container-fluid">
<div class="navbar-header">
<a class="navbar-brand" href="https://docs.fedoraproject.org/"><img alt="Fedora Documentation" src="../../../master/_images/fedora.svg"></a>
</div>
</div>
</div>
<div class="container">
<p class="toggle-nav visible-xs pull-left">
<button class="btn btn-default btn-sm" type="button" data-toggle="offcanvas">Toggle nav</button>
</p>
<ol class="breadcrumb">
<li class="sitename">
<a href="../../../index.html">Home</a>
</li>
<li class="hidden-xs active">
<a href="../../en-US/index.html">Defensive Coding Guide </a>
</li>
<li class="hidden-xs active">
<a href="../../en-US/index.html">Defensive Coding Guide</a>
</li>
<li class="hidden-xs active"><a href="../../en-US/tasks/Tasks-Library_Design.html">Specific Programming Tasks</a></li>
<li class="hidden-xs active">
Library Design
</li>
</ol>
<div class="row row-offcanvas row-offcanvas-left">
<div class="col-xs-8 col-sm-3 col-md-3 sidebar sidebar-offcanvas">
<ul class="nav nav-sidebar">
<li class="nav-header">
<a class="" href="#" data-toggle="collapse" data-target="#topicGroup0">
<span id="tgSpan0" class="fa fa-angle-down"></span>Defensive Coding Guide
</a>
<ul id="topicGroup0" class="collapse in list-unstyled">
<li><a class="" href="../../en-US/index.html">Book Information</a></li>
<li class="nav-header">
<a class="" href="#" data-toggle="collapse" data-target="#topicSubGroup-0-1">
<span id="sgSpan-0-1" class="fa fa-caret-right"></span>&nbsp;Programming Languages
</a>
<ul id="topicSubGroup-0-1" class="nav-tertiary list-unstyled collapse">
<li><a class="" href="../../en-US/programming-languages/C.html">The C Programming Language</a></li>
<li><a class="" href="../../en-US/programming-languages/CXX.html">The C++ Programming&nbsp;Language</a></li>
<li><a class="" href="../../en-US/programming-languages/Java.html">The Java Programming Language</a></li>
<li><a class="" href="../../en-US/programming-languages/Python.html">The Python Programming Language</a></li>
<li><a class="" href="../../en-US/programming-languages/Shell.html">Shell Programming and bash</a></li>
<li><a class="" href="../../en-US/programming-languages/Go.html">The Go Programming Language</a></li>
<li><a class="" href="../../en-US/programming-languages/Vala.html">The Vala Programming Language</a></li>
</ul>
</li>
<li class="nav-header">
<a class="" href="#" data-toggle="collapse" data-target="#topicSubGroup-0-2">
<span id="sgSpan-0-2" class="fa fa-caret-down"></span>&nbsp;Specific Programming Tasks
</a>
<ul id="topicSubGroup-0-2" class="nav-tertiary list-unstyled collapse in">
<li><a class=" active" href="../../en-US/tasks/Tasks-Library_Design.html">Library Design</a></li>
<li><a class="" href="../../en-US/tasks/Tasks-Descriptors.html">File Descriptor Management</a></li>
<li><a class="" href="../../en-US/tasks/Tasks-File_System.html">File System Manipulation</a></li>
<li><a class="" href="../../en-US/tasks/Tasks-Temporary_Files.html">Temporary Files</a></li>
<li><a class="" href="../../en-US/tasks/Tasks-Processes.html">Processes</a></li>
<li><a class="" href="../../en-US/tasks/Tasks-Serialization.html">Serialization and Deserialization</a></li>
<li><a class="" href="../../en-US/tasks/Tasks-Cryptography.html">Cryptography</a></li>
<li><a class="" href="../../en-US/tasks/Tasks-Packaging.html">RPM Packaging</a></li>
</ul>
</li>
<li class="nav-header">
<a class="" href="#" data-toggle="collapse" data-target="#topicSubGroup-0-3">
<span id="sgSpan-0-3" class="fa fa-caret-right"></span>&nbsp;Implementing Security Features
</a>
<ul id="topicSubGroup-0-3" class="nav-tertiary list-unstyled collapse">
<li><a class="" href="../../en-US/features/Features-Authentication.html">Authentication and Authorization</a></li>
<li><a class="" href="../../en-US/features/Features-TLS.html">Transport Layer Security (TLS)</a></li>
<li><a class="" href="../../en-US/features/Features-HSM.html">Hardware Security Modules and Smart Cards</a></li>
</ul>
</li>
<li><a class="" href="../../en-US/Revision_History.html">Revision History</a></li>
</ul>
</li>
</ul>
</div>
<div class="col-xs-12 col-sm-9 col-md-9 main">
<div class="page-header">
<h2>Library Design</h2>
</div>
<div id="preamble">
<div class="sectionbody">
<div class="paragraph">
<p>Through this section, the term <strong>client code</strong>
refers to applications and other libraries using the library.</p>
</div>
</div>
</div>
<div class="sect1">
<h2 id="state-management"><a class="anchor" href="#state-management"></a>State Management</h2>
<div class="sectionbody">
<div class="sect2">
<h3 id="global-state"><a class="anchor" href="#global-state"></a>Global State</h3>
<div class="paragraph">
<p>Global state should be avoided.</p>
</div>
<div class="paragraph">
<p>If this is impossible, the global state must be protected with
a lock. For C/C++, you can use the
<code>pthread_mutex_lock</code>
and <code>pthread_mutex_unlock</code>
functions without linking against <code>-lpthread</code>
because the system provides stubs for non-threaded processes.</p>
</div>
<div class="paragraph">
<p>For compatibility with <code>fork</code>, these locks
should be acquired and released in helpers registered with
<code>pthread_atfork</code>. This function is not
available without <code>-lpthread</code>, so you need to
use <code>dlsym</code> or a weak symbol to obtain its
address.</p>
</div>
<div class="paragraph">
<p>If you need <code>fork</code> protection for other
reasons, you should store the process ID and compare it to the
value returned by <code>getpid</code> each time you
access the global state. (<code>getpid</code> 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.)</p>
</div>
</div>
<div class="sect2">
<h3 id="handles"><a class="anchor" href="#handles"></a>Handles</h3>
<div class="paragraph">
<p>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 <code>struct</code>. In C++,
the handle can be a pointer to an abstract base class, or it
can be hidden using the pointer-to-implementation idiom.</p>
</div>
<div class="paragraph">
<p>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.)</p>
</div>
<div class="paragraph">
<p>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.</p>
</div>
<div class="paragraph">
<p>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.</p>
</div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="object-orientation"><a class="anchor" href="#object-orientation"></a>Object Orientation</h2>
<div class="sectionbody">
<div class="paragraph">
<p>Classes should be either designed as base classes, or it should
be impossible to use them as base classes (like
<code>final</code> 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.</p>
</div>
<div class="paragraph">
<p>Virtual member functions can be used as callbacks. See
<a href="#sect-Defensive_Coding-Tasks-Library_Design-Callbacks">Callbacks</a>
for some of the challenges involved.</p>
</div>
</div>
</div>
<div class="sect1">
<h2 id="sect-Defensive_Coding-Tasks-Library_Design-Callbacks"><a class="anchor" href="#sect-Defensive_Coding-Tasks-Library_Design-Callbacks"></a>Callbacks</h2>
<div class="sectionbody">
<div class="paragraph">
<p>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.</p>
</div>
<div class="paragraph">
<p>If callbacks are unavoidable, some guidelines for them follow.</p>
</div>
<div class="paragraph">
<p>In modern C++ code, <code>std::function</code> objects
should be used for callbacks.</p>
</div>
<div class="paragraph">
<p>In older C++ code and in C code, all callbacks must have an
additional closure parameter of type <code>void *</code>,
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.</p>
</div>
<div class="paragraph">
<p>Callbacks can throw exceptions or call
<code>longjmp</code>. 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.)</p>
</div>
<div class="paragraph">
<p>The presence of callbacks raises the question if functions
provided by the library are <strong>reentrant</strong>.
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.</p>
</div>
</div>
</div>
<div class="sect1">
<h2 id="process-attributes"><a class="anchor" href="#process-attributes"></a>Process Attributes</h2>
<div class="sectionbody">
<div class="paragraph">
<p>Several attributes are global and affect all code in the
process, not just the library that manipulates them.</p>
</div>
<div class="ulist">
<ul>
<li>
<p>environment variables
(see <a href="#sect-Defensive_Coding-Tasks-secure_getenv">[sect-Defensive_Coding-Tasks-secure_getenv]</a>)</p>
</li>
<li>
<p>umask</p>
</li>
<li>
<p>user IDs, group IDs and capabilities</p>
</li>
<li>
<p>current working directory</p>
</li>
<li>
<p>signal handlers, signal masks and signal delivery</p>
</li>
<li>
<p>file locks (especially <code>fcntl</code> locks
behave in surprising ways, not just in a multi-threaded
environment)</p>
</li>
</ul>
</div>
<div class="paragraph">
<p>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.</p>
</div>
<div class="paragraph">
<p>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.</p>
</div>
</div>
</div>
</div>
</div>
</div>
<div id="bottom" class="text-muted py-3" >
<div class="foot">
<div class="container">
<div class="row footerlinks">
<div class="col-sm-3 col-xs-6 widget">
<h3 class="widget-title">About</h3>
<div class="widget-body">
<dl>
<dd><a href="https://fedoraproject.org/wiki/Overview">About Fedora</a></dd>
<dd><a href="https://getfedora.org/en/sponsors">Sponsors</a></dd>
<dd><a href="https://fedoramagazine.org">Fedora Magazine</a></dd>
<dd><a href="https://fedoraproject.org/wiki/Legal:Main#Legal">Legal</a></dd>
</dl>
<ul class="list-inline">
<li>
<a href="https://www.facebook.com/TheFedoraProject" class="btn-social btn-outline"><i class="fa fa-fw fa-facebook"></i></a>
</li>
<li>
<a href="https://plus.google.com/112917221531140868607" class="btn-social btn-outline"><i class="fa fa-fw fa-google-plus"></i></a>
</li>
<li>
<a href="https://twitter.com/fedora" class="btn-social btn-outline"><i class="fa fa-fw fa-twitter"></i></a>
</li>
</ul>
</div>
</div>
<div class="col-sm-3 col-xs-6 widget">
<h3 class="widget-title uppercase">Download</h3>
<div class="widget-body">
<dl>
<dd><a href="https://getfedora.org/en/workstation/download">Get Fedora Workstation</a></dd>
<dd><a href="https://getfedora.org/en/server/download">Get Fedora Server</a></dd>
<dd><a href="https://getfedora.org/en/atomic/download">Get Fedora Atomic</a></dd>
<dd><a href="https://spins.fedoraproject.org">Fedora Spins</a></dd>
<dd><a href="https://labs.fedoraproject.org">Fedora Labs</a></dd>
<dd><a href="https://arm.fedoraproject.org">Fedora ARM<span class="sup">&reg;</span></a></dd>
<dd><a href="https://alt.fedoraproject.org/">Alternative Downloads</a></dd>
</dl>
</div>
</div>
<div class="col-sm-3 col-xs-6 widget">
<h3 class="widget-title">Support</h3>
<div class="widget-body">
<dl>
<dd><a href="https://fedoraproject.org/wiki/Communicating_and_getting_help">Get Help</a></dd>
<dd><a href="https://ask.fedoraproject.org/">Ask Fedora</a></dd>
<dd><a href="https://fedoraproject.org/wiki/Common_F27_bugs">Common Bugs</a></dd>
<dd><a href="https://developer.fedoraproject.org/">Fedora Developer Portal</a></dd>
<dd><a href="https://docs.fedoraproject.org/f27/install-guide/index.html">Installation Guide</a></dd>
</dl>
</div>
</div>
<div class="col-sm-3 col-xs-6 widget">
<h3 class="widget-title">Join</h3>
<div class="widget-body">
<dl>
<dd><a href="https://fedoraproject.org/wiki/Join">Join Fedora</a></dd>
<dd><a href="http://fedoraplanet.org">Planet Fedora</a></dd>
<dd><a href="https://fedoraproject.org/wiki/SIGs">Fedora SIGs</a></dd>
<dd><a href="https://admin.fedoraproject.org/accounts/">Fedora Account System</a></dd>
<dd><a href="https://fedoracommunity.org/">Fedora Community</a></dd>
</dl>
</div>
</div>
</div> <!-- /row of widgets -->
<div class="row">
<div class="col-md-2">
<div class="widget-body">
<a href="https://www.redhat.com/"><img class="rh-logo" src="../../../master/_images/redhat-logo.png" alt="Red Hat Logo" /></a>
</div>
</div>
<div class="col-md-7">
<div class="widget-body">
<p class="sponsor">Fedora is sponsored by Red Hat.</p>
<p class="sponsor"><a href="https://www.redhat.com/en/technologies/linux-platforms/articles/relationship-between-fedora-and-rhel">Learn more about the relationship between Red Hat and Fedora &raquo;</a></p>
<p class="copy">&copy; 2017 Red Hat, Inc. and others. Please send any comments or corrections to the <a href="https://pagure.io/fedora-docs/docs-fp-o">documentation team</a></p>
</div>
</div>
</div> <!-- /row of widgets -->
</div>
</div>
</div>
<!-- jQuery (necessary for Bootstrap's JavaScript plugins) -->
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>
<!-- Latest compiled and minified JavaScript -->
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/js/bootstrap.min.js"></script>
<script src="../../../master/_javascripts/bootstrap-offcanvas.js" type="text/javascript"></script>
<script type="text/javascript">
/*<![CDATA[*/
$(document).ready(function() {
$("[id^='topicGroup']").on('show.bs.collapse', function (event) {
if (!($(event.target).attr('id').match(/^topicSubGroup/))) {
$(this).parent().find("[id^='tgSpan']").toggleClass("fa-angle-right fa-angle-down");
}
});
$("[id^='topicGroup']").on('hide.bs.collapse', function (event) {
if (!($(event.target).attr('id').match(/^topicSubGroup/))) {
$(this).parent().find("[id^='tgSpan']").toggleClass("fa-angle-right fa-angle-down");
}
});
$("[id^='topicSubGroup']").on('show.bs.collapse', function () {
$(this).parent().find("[id^='sgSpan']").toggleClass("fa-caret-right fa-caret-down");
});
$("[id^='topicSubGroup']").on('hide.bs.collapse', function () {
$(this).parent().find("[id^='sgSpan']").toggleClass("fa-caret-right fa-caret-down");
});
});
/*]]>*/
</script>
</body>
</html>

View file

@ -1,438 +0,0 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta content="IE=edge" http-equiv="X-UA-Compatible">
<meta content="width=device-width, initial-scale=1.0" name="viewport">
<title>Defensive Coding Guide | Defensive Coding Guide | Specific Programming Tasks | RPM Packaging</title>
<!-- Bootstrap -->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css">
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap-theme.min.css">
<!-- Overpass Font -->
<link rel="stylesheet" href="https://overpass-30e2.kxcdn.com/overpass.css">
<link href="../../../master/_stylesheets/asciibinder.css" rel="stylesheet" />
<!-- HTML5 shim and Respond.js for IE8 support of HTML5 elements and media queries -->
<!-- WARNING: Respond.js doesn't work if you view the page via file:// -->
<!--[if lt IE 9]>
<script src="https://oss.maxcdn.com/html5shiv/3.7.2/html5shiv.min.js"></script>
<script src="https://oss.maxcdn.com/respond/1.4.2/respond.min.js"></script>
<![endif]-->
<link href="../../../master/_images/favicon32x32.png" rel="shortcut icon" type="text/css">
<!--[if IE]><link rel="shortcut icon" href="../../../master/_images/favicon.ico"><![endif]-->
<meta content="AsciiBinder" name="application-name">
</head>
<body>
<div class="navbar navbar-default" role="navigation">
<div class="container-fluid">
<div class="navbar-header">
<a class="navbar-brand" href="https://docs.fedoraproject.org/"><img alt="Fedora Documentation" src="../../../master/_images/fedora.svg"></a>
</div>
</div>
</div>
<div class="container">
<p class="toggle-nav visible-xs pull-left">
<button class="btn btn-default btn-sm" type="button" data-toggle="offcanvas">Toggle nav</button>
</p>
<ol class="breadcrumb">
<li class="sitename">
<a href="../../../index.html">Home</a>
</li>
<li class="hidden-xs active">
<a href="../../en-US/index.html">Defensive Coding Guide </a>
</li>
<li class="hidden-xs active">
<a href="../../en-US/index.html">Defensive Coding Guide</a>
</li>
<li class="hidden-xs active"><a href="../../en-US/tasks/Tasks-Library_Design.html">Specific Programming Tasks</a></li>
<li class="hidden-xs active">
RPM Packaging
</li>
</ol>
<div class="row row-offcanvas row-offcanvas-left">
<div class="col-xs-8 col-sm-3 col-md-3 sidebar sidebar-offcanvas">
<ul class="nav nav-sidebar">
<li class="nav-header">
<a class="" href="#" data-toggle="collapse" data-target="#topicGroup0">
<span id="tgSpan0" class="fa fa-angle-down"></span>Defensive Coding Guide
</a>
<ul id="topicGroup0" class="collapse in list-unstyled">
<li><a class="" href="../../en-US/index.html">Book Information</a></li>
<li class="nav-header">
<a class="" href="#" data-toggle="collapse" data-target="#topicSubGroup-0-1">
<span id="sgSpan-0-1" class="fa fa-caret-right"></span>&nbsp;Programming Languages
</a>
<ul id="topicSubGroup-0-1" class="nav-tertiary list-unstyled collapse">
<li><a class="" href="../../en-US/programming-languages/C.html">The C Programming Language</a></li>
<li><a class="" href="../../en-US/programming-languages/CXX.html">The C++ Programming&nbsp;Language</a></li>
<li><a class="" href="../../en-US/programming-languages/Java.html">The Java Programming Language</a></li>
<li><a class="" href="../../en-US/programming-languages/Python.html">The Python Programming Language</a></li>
<li><a class="" href="../../en-US/programming-languages/Shell.html">Shell Programming and bash</a></li>
<li><a class="" href="../../en-US/programming-languages/Go.html">The Go Programming Language</a></li>
<li><a class="" href="../../en-US/programming-languages/Vala.html">The Vala Programming Language</a></li>
</ul>
</li>
<li class="nav-header">
<a class="" href="#" data-toggle="collapse" data-target="#topicSubGroup-0-2">
<span id="sgSpan-0-2" class="fa fa-caret-down"></span>&nbsp;Specific Programming Tasks
</a>
<ul id="topicSubGroup-0-2" class="nav-tertiary list-unstyled collapse in">
<li><a class="" href="../../en-US/tasks/Tasks-Library_Design.html">Library Design</a></li>
<li><a class="" href="../../en-US/tasks/Tasks-Descriptors.html">File Descriptor Management</a></li>
<li><a class="" href="../../en-US/tasks/Tasks-File_System.html">File System Manipulation</a></li>
<li><a class="" href="../../en-US/tasks/Tasks-Temporary_Files.html">Temporary Files</a></li>
<li><a class="" href="../../en-US/tasks/Tasks-Processes.html">Processes</a></li>
<li><a class="" href="../../en-US/tasks/Tasks-Serialization.html">Serialization and Deserialization</a></li>
<li><a class="" href="../../en-US/tasks/Tasks-Cryptography.html">Cryptography</a></li>
<li><a class=" active" href="../../en-US/tasks/Tasks-Packaging.html">RPM Packaging</a></li>
</ul>
</li>
<li class="nav-header">
<a class="" href="#" data-toggle="collapse" data-target="#topicSubGroup-0-3">
<span id="sgSpan-0-3" class="fa fa-caret-right"></span>&nbsp;Implementing Security Features
</a>
<ul id="topicSubGroup-0-3" class="nav-tertiary list-unstyled collapse">
<li><a class="" href="../../en-US/features/Features-Authentication.html">Authentication and Authorization</a></li>
<li><a class="" href="../../en-US/features/Features-TLS.html">Transport Layer Security (TLS)</a></li>
<li><a class="" href="../../en-US/features/Features-HSM.html">Hardware Security Modules and Smart Cards</a></li>
</ul>
</li>
<li><a class="" href="../../en-US/Revision_History.html">Revision History</a></li>
</ul>
</li>
</ul>
</div>
<div class="col-xs-12 col-sm-9 col-md-9 main">
<div class="page-header">
<h2>RPM Packaging</h2>
</div>
<div id="preamble">
<div class="sectionbody">
<div class="paragraph">
<p>This chapter deals with security-related concerns around RPM
packaging. It has to be read in conjunction with
distribution-specific packaging guidelines.</p>
</div>
</div>
</div>
<div class="sect1">
<h2 id="sect-Defensive_Coding-Tasks-Packaging-Certificates"><a class="anchor" href="#sect-Defensive_Coding-Tasks-Packaging-Certificates"></a>Generating X.509 Self-signed Certificates during Installation</h2>
<div class="sectionbody">
<div class="paragraph">
<p>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 <a href="#sect-Defensive_Coding-Tasks-Packaging-Certificates-Service">Generating X.509 Self-signed Certificates before Service Start</a>,
and <a href="https://fedoraproject.org/wiki/Packaging:Initial_Service_Setup#Generating_Self-Signed_Certificates">Packaging:Initial Service Setup</a>.</p>
</div>
<div class="admonitionblock important">
<table>
<tr>
<td class="icon">
<i class="fa icon-important" title="Important"></i>
</td>
<td class="content">
<div class="paragraph">
<p>The way the key is generated may not be suitable for key
material of critical value. (<code class="command">openssl
genrsa</code> 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.</p>
</div>
</td>
</tr>
</table>
</div>
<div class="paragraph">
<p>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:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code data-lang="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</code></pre>
</div>
</div>
<div class="paragraph">
<p>These variables likely need adjustment based on the needs of the
package.</p>
</div>
<div class="paragraph">
<p>Typically, the file with the private key needs to be owned by
the system user which needs to read it,
<code>%{tlsuser}</code> (not <code>root</code>). In
order to avoid races, if the <strong>directory</strong>
<code>%{tlsdir}</code> is <strong>owned by the services
user</strong>, you should use the code in <a href="#ex-Defensive_Coding-Packaging-Certificates-Owned">Creating a key pair in a user-owned directory</a>.
The invocation of <strong class="application">su</strong> with the
<code class="option">-s /bin/bash</code> argument is necessary in case the
login shell for the user has been disabled.</p>
</div>
<div id="ex-Defensive_Coding-Packaging-Certificates-Owned" class="exampleblock">
<div class="title">Example 1. Creating a key pair in a user-owned directory</div>
<div class="content">
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code data-lang="bash">%post
if [ $1 -eq 1 ] ; then
if ! test -e %{tlskey} ; then
su -s /bin/bash \
-c &quot;umask 077 &amp;&amp; openssl genrsa -out %{tlskey} 2048 2&gt;/dev/null&quot; \
%{tlsuser}
fi
if ! test -e %{tlscert} ; then
cn=&quot;Automatically generated certificate for the %{tlsuser} service&quot;
req_args=&quot;-key %{tlskey} -out %{tlscert} -days 7305 -subj \&quot;/CN=$cn/\&quot;&quot;
su -s /bin/bash \
-c &quot;openssl req -new -x509 -extensions usr_cert $req_args&quot; \
%{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}</code></pre>
</div>
</div>
</div>
</div>
<div class="paragraph">
<p>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 <code>%ghost</code>), or delete the files
when the package is uninstalled (the
<code>%config(noreplace)</code> part).</p>
</div>
<div class="paragraph">
<p>If the <strong>directory</strong>
<code>%{tlsdir}</code> <strong>is owned by</strong>
<code>root</code>, use the code in <a href="#ex-Defensive_Coding-Packaging-Certificates-Unowned">Creating a key pair in a <code>root</code>-owned directory</a>.</p>
</div>
<div id="ex-Defensive_Coding-Packaging-Certificates-Unowned" class="exampleblock">
<div class="title">Example 2. Creating a key pair in a <code>root</code>-owned directory</div>
<div class="content">
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code data-lang="bash">%post
if [ $1 -eq 1 ] ; then
if ! test -e %{tlskey} ; then
(umask 077 &amp;&amp; openssl genrsa -out %{tlskey} 2048 2&gt;/dev/null)
chown %{tlsuser} %{tlskey}
fi
if ! test -e %{tlscert} ; then
cn=&quot;Automatically generated certificate for the %{tlsuser} service&quot;
openssl req -new -x509 -extensions usr_cert \
-key %{tlskey} -out %{tlscert} -days 7305 -subj &quot;/CN=$cn/&quot;
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}</code></pre>
</div>
</div>
</div>
</div>
<div class="paragraph">
<p>In order for this to work, the package which generates the keys
must require the <strong class="application">openssl</strong> package. If
the user which owns the key file is generated by a different
package, the package generating the certificate must specify a
<code>Requires(pre):</code> on the package which creates
the user. This ensures that the user account will exist when it
is needed for the <strong class="application">su</strong> or
<strong class="application">chmod</strong> invocation.</p>
</div>
</div>
</div>
<div class="sect1">
<h2 id="sect-Defensive_Coding-Tasks-Packaging-Certificates-Service"><a class="anchor" href="#sect-Defensive_Coding-Tasks-Packaging-Certificates-Service"></a>Generating X.509 Self-signed Certificates before Service Start</h2>
<div class="sectionbody">
<div class="paragraph">
<p>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 <a href="#sect-Defensive_Coding-Tasks-Packaging-Certificates">Generating X.509 Self-signed Certificates during Installation</a>)
would put the key into the image, which may or may not make
sense.</p>
</div>
<div class="admonitionblock important">
<table>
<tr>
<td class="icon">
<i class="fa icon-important" title="Important"></i>
</td>
<td class="content">
<div class="paragraph">
<p>The caveats about the way the key is generated in <a href="#sect-Defensive_Coding-Tasks-Packaging-Certificates">Generating X.509 Self-signed Certificates during Installation</a>
apply to this procedure as well.</p>
</div>
</td>
</tr>
</table>
</div>
<div class="paragraph">
<p>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
<code>random: nonblocking pool is initialized</code>, or
ensure that the application used for generating the keys
is utilizing the <code>getrandom()</code> system call.</p>
</div>
<div class="paragraph">
<p>In theory, it is also possible to use an application which reads from
<code>/dev/random</code> while generating the key
material (instead of <code>/dev/urandom</code>), 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.</p>
</div>
<div class="paragraph">
<p>The requirements for generating such keys is documented at
<a href="https://fedoraproject.org/wiki/Packaging:Initial_Service_Setup#Generating_Self-Signed_Certificates">Packaging:Initial Service Setup</a>.</p>
</div>
</div>
</div>
</div>
</div>
</div>
<div id="bottom" class="text-muted py-3" >
<div class="foot">
<div class="container">
<div class="row footerlinks">
<div class="col-sm-3 col-xs-6 widget">
<h3 class="widget-title">About</h3>
<div class="widget-body">
<dl>
<dd><a href="https://fedoraproject.org/wiki/Overview">About Fedora</a></dd>
<dd><a href="https://getfedora.org/en/sponsors">Sponsors</a></dd>
<dd><a href="https://fedoramagazine.org">Fedora Magazine</a></dd>
<dd><a href="https://fedoraproject.org/wiki/Legal:Main#Legal">Legal</a></dd>
</dl>
<ul class="list-inline">
<li>
<a href="https://www.facebook.com/TheFedoraProject" class="btn-social btn-outline"><i class="fa fa-fw fa-facebook"></i></a>
</li>
<li>
<a href="https://plus.google.com/112917221531140868607" class="btn-social btn-outline"><i class="fa fa-fw fa-google-plus"></i></a>
</li>
<li>
<a href="https://twitter.com/fedora" class="btn-social btn-outline"><i class="fa fa-fw fa-twitter"></i></a>
</li>
</ul>
</div>
</div>
<div class="col-sm-3 col-xs-6 widget">
<h3 class="widget-title uppercase">Download</h3>
<div class="widget-body">
<dl>
<dd><a href="https://getfedora.org/en/workstation/download">Get Fedora Workstation</a></dd>
<dd><a href="https://getfedora.org/en/server/download">Get Fedora Server</a></dd>
<dd><a href="https://getfedora.org/en/atomic/download">Get Fedora Atomic</a></dd>
<dd><a href="https://spins.fedoraproject.org">Fedora Spins</a></dd>
<dd><a href="https://labs.fedoraproject.org">Fedora Labs</a></dd>
<dd><a href="https://arm.fedoraproject.org">Fedora ARM<span class="sup">&reg;</span></a></dd>
<dd><a href="https://alt.fedoraproject.org/">Alternative Downloads</a></dd>
</dl>
</div>
</div>
<div class="col-sm-3 col-xs-6 widget">
<h3 class="widget-title">Support</h3>
<div class="widget-body">
<dl>
<dd><a href="https://fedoraproject.org/wiki/Communicating_and_getting_help">Get Help</a></dd>
<dd><a href="https://ask.fedoraproject.org/">Ask Fedora</a></dd>
<dd><a href="https://fedoraproject.org/wiki/Common_F27_bugs">Common Bugs</a></dd>
<dd><a href="https://developer.fedoraproject.org/">Fedora Developer Portal</a></dd>
<dd><a href="https://docs.fedoraproject.org/f27/install-guide/index.html">Installation Guide</a></dd>
</dl>
</div>
</div>
<div class="col-sm-3 col-xs-6 widget">
<h3 class="widget-title">Join</h3>
<div class="widget-body">
<dl>
<dd><a href="https://fedoraproject.org/wiki/Join">Join Fedora</a></dd>
<dd><a href="http://fedoraplanet.org">Planet Fedora</a></dd>
<dd><a href="https://fedoraproject.org/wiki/SIGs">Fedora SIGs</a></dd>
<dd><a href="https://admin.fedoraproject.org/accounts/">Fedora Account System</a></dd>
<dd><a href="https://fedoracommunity.org/">Fedora Community</a></dd>
</dl>
</div>
</div>
</div> <!-- /row of widgets -->
<div class="row">
<div class="col-md-2">
<div class="widget-body">
<a href="https://www.redhat.com/"><img class="rh-logo" src="../../../master/_images/redhat-logo.png" alt="Red Hat Logo" /></a>
</div>
</div>
<div class="col-md-7">
<div class="widget-body">
<p class="sponsor">Fedora is sponsored by Red Hat.</p>
<p class="sponsor"><a href="https://www.redhat.com/en/technologies/linux-platforms/articles/relationship-between-fedora-and-rhel">Learn more about the relationship between Red Hat and Fedora &raquo;</a></p>
<p class="copy">&copy; 2017 Red Hat, Inc. and others. Please send any comments or corrections to the <a href="https://pagure.io/fedora-docs/docs-fp-o">documentation team</a></p>
</div>
</div>
</div> <!-- /row of widgets -->
</div>
</div>
</div>
<!-- jQuery (necessary for Bootstrap's JavaScript plugins) -->
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>
<!-- Latest compiled and minified JavaScript -->
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/js/bootstrap.min.js"></script>
<script src="../../../master/_javascripts/bootstrap-offcanvas.js" type="text/javascript"></script>
<script type="text/javascript">
/*<![CDATA[*/
$(document).ready(function() {
$("[id^='topicGroup']").on('show.bs.collapse', function (event) {
if (!($(event.target).attr('id').match(/^topicSubGroup/))) {
$(this).parent().find("[id^='tgSpan']").toggleClass("fa-angle-right fa-angle-down");
}
});
$("[id^='topicGroup']").on('hide.bs.collapse', function (event) {
if (!($(event.target).attr('id').match(/^topicSubGroup/))) {
$(this).parent().find("[id^='tgSpan']").toggleClass("fa-angle-right fa-angle-down");
}
});
$("[id^='topicSubGroup']").on('show.bs.collapse', function () {
$(this).parent().find("[id^='sgSpan']").toggleClass("fa-caret-right fa-caret-down");
});
$("[id^='topicSubGroup']").on('hide.bs.collapse', function () {
$(this).parent().find("[id^='sgSpan']").toggleClass("fa-caret-right fa-caret-down");
});
});
/*]]>*/
</script>
</body>
</html>

View file

@ -1,702 +0,0 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta content="IE=edge" http-equiv="X-UA-Compatible">
<meta content="width=device-width, initial-scale=1.0" name="viewport">
<title>Defensive Coding Guide | Defensive Coding Guide | Specific Programming Tasks | Processes</title>
<!-- Bootstrap -->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css">
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap-theme.min.css">
<!-- Overpass Font -->
<link rel="stylesheet" href="https://overpass-30e2.kxcdn.com/overpass.css">
<link href="../../../master/_stylesheets/asciibinder.css" rel="stylesheet" />
<!-- HTML5 shim and Respond.js for IE8 support of HTML5 elements and media queries -->
<!-- WARNING: Respond.js doesn't work if you view the page via file:// -->
<!--[if lt IE 9]>
<script src="https://oss.maxcdn.com/html5shiv/3.7.2/html5shiv.min.js"></script>
<script src="https://oss.maxcdn.com/respond/1.4.2/respond.min.js"></script>
<![endif]-->
<link href="../../../master/_images/favicon32x32.png" rel="shortcut icon" type="text/css">
<!--[if IE]><link rel="shortcut icon" href="../../../master/_images/favicon.ico"><![endif]-->
<meta content="AsciiBinder" name="application-name">
</head>
<body>
<div class="navbar navbar-default" role="navigation">
<div class="container-fluid">
<div class="navbar-header">
<a class="navbar-brand" href="https://docs.fedoraproject.org/"><img alt="Fedora Documentation" src="../../../master/_images/fedora.svg"></a>
</div>
</div>
</div>
<div class="container">
<p class="toggle-nav visible-xs pull-left">
<button class="btn btn-default btn-sm" type="button" data-toggle="offcanvas">Toggle nav</button>
</p>
<ol class="breadcrumb">
<li class="sitename">
<a href="../../../index.html">Home</a>
</li>
<li class="hidden-xs active">
<a href="../../en-US/index.html">Defensive Coding Guide </a>
</li>
<li class="hidden-xs active">
<a href="../../en-US/index.html">Defensive Coding Guide</a>
</li>
<li class="hidden-xs active"><a href="../../en-US/tasks/Tasks-Library_Design.html">Specific Programming Tasks</a></li>
<li class="hidden-xs active">
Processes
</li>
</ol>
<div class="row row-offcanvas row-offcanvas-left">
<div class="col-xs-8 col-sm-3 col-md-3 sidebar sidebar-offcanvas">
<ul class="nav nav-sidebar">
<li class="nav-header">
<a class="" href="#" data-toggle="collapse" data-target="#topicGroup0">
<span id="tgSpan0" class="fa fa-angle-down"></span>Defensive Coding Guide
</a>
<ul id="topicGroup0" class="collapse in list-unstyled">
<li><a class="" href="../../en-US/index.html">Book Information</a></li>
<li class="nav-header">
<a class="" href="#" data-toggle="collapse" data-target="#topicSubGroup-0-1">
<span id="sgSpan-0-1" class="fa fa-caret-right"></span>&nbsp;Programming Languages
</a>
<ul id="topicSubGroup-0-1" class="nav-tertiary list-unstyled collapse">
<li><a class="" href="../../en-US/programming-languages/C.html">The C Programming Language</a></li>
<li><a class="" href="../../en-US/programming-languages/CXX.html">The C++ Programming&nbsp;Language</a></li>
<li><a class="" href="../../en-US/programming-languages/Java.html">The Java Programming Language</a></li>
<li><a class="" href="../../en-US/programming-languages/Python.html">The Python Programming Language</a></li>
<li><a class="" href="../../en-US/programming-languages/Shell.html">Shell Programming and bash</a></li>
<li><a class="" href="../../en-US/programming-languages/Go.html">The Go Programming Language</a></li>
<li><a class="" href="../../en-US/programming-languages/Vala.html">The Vala Programming Language</a></li>
</ul>
</li>
<li class="nav-header">
<a class="" href="#" data-toggle="collapse" data-target="#topicSubGroup-0-2">
<span id="sgSpan-0-2" class="fa fa-caret-down"></span>&nbsp;Specific Programming Tasks
</a>
<ul id="topicSubGroup-0-2" class="nav-tertiary list-unstyled collapse in">
<li><a class="" href="../../en-US/tasks/Tasks-Library_Design.html">Library Design</a></li>
<li><a class="" href="../../en-US/tasks/Tasks-Descriptors.html">File Descriptor Management</a></li>
<li><a class="" href="../../en-US/tasks/Tasks-File_System.html">File System Manipulation</a></li>
<li><a class="" href="../../en-US/tasks/Tasks-Temporary_Files.html">Temporary Files</a></li>
<li><a class=" active" href="../../en-US/tasks/Tasks-Processes.html">Processes</a></li>
<li><a class="" href="../../en-US/tasks/Tasks-Serialization.html">Serialization and Deserialization</a></li>
<li><a class="" href="../../en-US/tasks/Tasks-Cryptography.html">Cryptography</a></li>
<li><a class="" href="../../en-US/tasks/Tasks-Packaging.html">RPM Packaging</a></li>
</ul>
</li>
<li class="nav-header">
<a class="" href="#" data-toggle="collapse" data-target="#topicSubGroup-0-3">
<span id="sgSpan-0-3" class="fa fa-caret-right"></span>&nbsp;Implementing Security Features
</a>
<ul id="topicSubGroup-0-3" class="nav-tertiary list-unstyled collapse">
<li><a class="" href="../../en-US/features/Features-Authentication.html">Authentication and Authorization</a></li>
<li><a class="" href="../../en-US/features/Features-TLS.html">Transport Layer Security (TLS)</a></li>
<li><a class="" href="../../en-US/features/Features-HSM.html">Hardware Security Modules and Smart Cards</a></li>
</ul>
</li>
<li><a class="" href="../../en-US/Revision_History.html">Revision History</a></li>
</ul>
</li>
</ul>
</div>
<div class="col-xs-12 col-sm-9 col-md-9 main">
<div class="page-header">
<h2>Processes</h2>
</div>
<div class="sect1">
<h2 id="sect-Defensive_Coding-Tasks-Processes-Creation"><a class="anchor" href="#sect-Defensive_Coding-Tasks-Processes-Creation"></a>Creating Safe Processes</h2>
<div class="sectionbody">
<div class="paragraph">
<p>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 <a href="#sect-Defensive_Coding-Tasks-Descriptors-Child_Processes">[sect-Defensive_Coding-Tasks-Descriptors-Child_Processes]</a>.</p>
</div>
<div class="sect2">
<h3 id="obtaining-the-program-path-and-the-command-line-template"><a class="anchor" href="#obtaining-the-program-path-and-the-command-line-template"></a>Obtaining the Program Path and the Command-line Template</h3>
<div class="paragraph">
<p>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.</p>
</div>
<div class="paragraph">
<p>The configured program name should be an absolute path. If it
is a relative path, the contents of the <code>PATH</code>
must be obtained in a secure manner (see <a href="#sect-Defensive_Coding-Tasks-secure_getenv">Accessing Environment Variables</a>).
If the <code>PATH</code> variable is not set or untrusted,
the safe default <code>/bin:/usr/bin</code> must be
used.</p>
</div>
<div class="paragraph">
<p>If too much flexibility is provided here, it may allow
invocation of arbitrary programs without proper authorization.</p>
</div>
</div>
<div class="sect2">
<h3 id="sect-Defensive_Coding-Tasks-Processes-execve"><a class="anchor" href="#sect-Defensive_Coding-Tasks-Processes-execve"></a>Bypassing the Shell</h3>
<div class="paragraph">
<p>Child processes should be created without involving the system
shell.</p>
</div>
<div class="paragraph">
<p>For C/C++, <code>system</code> should not be used.
The <code>posix_spawn</code> function can be used
instead, or a combination <code>fork</code> and
<code>execve</code>. (In some cases, it may be
preferable to use <code>vfork</code> or the
Linux-specific <code>clone</code> system call instead
of <code>fork</code>.)</p>
</div>
<div class="paragraph">
<p>In Python, the <code>subprocess</code> module bypasses
the shell by default (when the <code>shell</code>
keyword argument is not set to true).
<code>os.system</code> should not be used.</p>
</div>
<div class="paragraph">
<p>The Java class <code>java.lang.ProcessBuilder</code> can be
used to create subprocesses without interference from the
system shell.</p>
</div>
<div class="admonitionblock important">
<table>
<tr>
<td class="icon">
<i class="fa icon-important" title="Important"></i>
</td>
<td class="content">
<div class="title">Portability notice</div>
<div class="paragraph">
<p>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.</p>
</div>
</td>
</tr>
</table>
</div>
<div class="paragraph">
<p>Note that some common applications (notably
<strong class="application">ssh</strong>) 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.</p>
</div>
</div>
<div class="sect2">
<h3 id="sect-Defensive_Coding-Tasks-Processes-environ"><a class="anchor" href="#sect-Defensive_Coding-Tasks-Processes-environ"></a>Specifying the Process Environment</h3>
<div class="paragraph">
<p>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.</p>
</div>
<div class="paragraph">
<p>In C/C++, the environment should be constructed as an array of
strings and passed as the <code>envp</code> argument to
<code>posix_spawn</code> or <code>execve</code>.
The functions <code>setenv</code>,
<code>unsetenv</code> and <code>putenv</code>
should not be used. They are not thread-safe and suffer from
memory leaks.</p>
</div>
<div class="paragraph">
<p>Python programs need to specify a <code>dict</code> for
the the <code>env</code> argument of the
<code>subprocess.Popen</code> constructor.
The Java class <code>java.lang.ProcessBuilder</code>
provides a <code>environment()</code> method,
which returns a map that can be manipulated.</p>
</div>
<div class="paragraph">
<p>The following list provides guidelines for selecting the set
of environment variables passed to the child process.</p>
</div>
<div class="ulist">
<ul>
<li>
<p><code>PATH</code> should be initialized to
<code>/bin:/usr/bin</code>.</p>
</li>
<li>
<p><code>USER</code> and <code>HOME</code> can be inhereted
from the parent process environment, or they can be
initialized from the <code>pwent</code> structure
for the user.</p>
</li>
<li>
<p>The <code>DISPLAY</code> and <code>XAUTHORITY</code>
variables should be passed to the subprocess if it is an X
program. Note that this will typically not work across trust
boundaries because <code>XAUTHORITY</code> refers to a file
with <code>0600</code> permissions.</p>
</li>
<li>
<p>The location-related environment variables
<code>LANG</code>, <code>LANGUAGE</code>,
<code>LC_ADDRESS</code>, <code>LC_ALL</code>,
<code>LC_COLLATE</code>, <code>LC_CTYPE</code>,
<code>LC_IDENTIFICATION</code>,
<code>LC_MEASUREMENT</code>, <code>LC_MESSAGES</code>,
<code>LC_MONETARY</code>, <code>LC_NAME</code>,
<code>LC_NUMERIC</code>, <code>LC_PAPER</code>,
<code>LC_TELEPHONE</code> and <code>LC_TIME</code>
can be passed to the subprocess if present.</p>
</li>
<li>
<p>The called process may need application-specific
environment variables, for example for passing passwords.
(See <a href="#sect-Defensive_Coding-Tasks-Processes-Command_Line_Visibility">Passing Secrets to Subprocesses</a>.)</p>
</li>
<li>
<p>All other environment variables should be dropped. Names
for new environment variables should not be accepted from
untrusted sources.</p>
</li>
</ul>
</div>
</div>
<div class="sect2">
<h3 id="robust-argument-list-processing"><a class="anchor" href="#robust-argument-list-processing"></a>Robust Argument List Processing</h3>
<div class="paragraph">
<p>When invoking a program, it is sometimes necessary to include
data from untrusted sources. Such data should be checked
against embedded <code>NUL</code> characters because the
system APIs will silently truncate argument strings at the first
<code>NUL</code> character.</p>
</div>
<div class="paragraph">
<p>The following recommendations assume that the program being
invoked uses GNU-style option processing using
<code>getopt_long</code>. This convention is widely
used, but it is just that, and individual programs might
interpret a command line in a different way.</p>
</div>
<div class="paragraph">
<p>If the untrusted data has to go into an option, use the
<code>--option-name=VALUE</code> syntax, placing the
option and its value into the same command line argument.
This avoids any potential confusion if the data starts with
<code>-</code>.</p>
</div>
<div class="paragraph">
<p>For positional arguments, terminate the option list with a
single <code class="option">--</code> marker after the last option, and
include the data at the right position. The
<code class="option">--</code> marker terminates option processing, and
the data will not be treated as an option even if it starts
with a dash.</p>
</div>
</div>
<div class="sect2">
<h3 id="sect-Defensive_Coding-Tasks-Processes-Command_Line_Visibility"><a class="anchor" href="#sect-Defensive_Coding-Tasks-Processes-Command_Line_Visibility"></a>Passing Secrets to Subprocesses</h3>
<div class="paragraph">
<p>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 <a href="#sect-Defensive_Coding-Tasks-Processes-environ">Specifying the Process Environment</a>.)</p>
</div>
<div class="admonitionblock important">
<table>
<tr>
<td class="icon">
<i class="fa icon-important" title="Important"></i>
</td>
<td class="content">
<div class="title">Portability notice</div>
<div class="paragraph">
<p>On some UNIX-like systems (notably Solaris), environment
variables can be read by any system user, just like command
lines.</p>
</div>
</td>
</tr>
</table>
</div>
<div class="paragraph">
<p>If the environment-based approach cannot be used due to
portability concerns, the data can be passed on standard
input. Some programs (notably <strong class="application">gpg</strong>)
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.</p>
</div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="handling-child-process-termination"><a class="anchor" href="#handling-child-process-termination"></a>Handling Child Process Termination</h2>
<div class="sectionbody">
<div class="paragraph">
<p>When child processes terminate, the parent process is signalled.
A stub of the terminated processes (a
<strong>zombie</strong>, shown as
<code>&lt;defunct&gt;</code> by
<strong class="application">ps</strong>) is kept around until the status
information is collected (<strong>reaped</strong>) by the
parent process. Over the years, several interfaces for this
have been invented:</p>
</div>
<div class="ulist">
<ul>
<li>
<p>The parent process calls <code>wait</code>,
<code>waitpid</code>, <code>waitid</code>,
<code>wait3</code> or <code>wait4</code>,
without specifying a process ID. This will deliver any
matching process ID. This approach is typically used from
within event loops.</p>
</li>
<li>
<p>The parent process calls <code>waitpid</code>,
<code>waitid</code>, or <code>wait4</code>,
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.</p>
</li>
<li>
<p>The parent process installs a handler for the
<code>SIGCHLD</code> signal, using
<code>sigaction</code>, and specifies to the
<code>SA_NOCLDWAIT</code> flag.
This approach could be used by event loops as well.</p>
</li>
</ul>
</div>
<div class="paragraph">
<p>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).</p>
</div>
<div class="paragraph">
<p>At the moment, the parent process should explicitly wait for
termination of the child process using
<code>waitpid</code> or <code>waitid</code>,
and hope that the status is not collected by an event loop
first.</p>
</div>
</div>
</div>
<div class="sect1">
<h2 id="code-suid-code-code-sgid-code-processes"><a class="anchor" href="#code-suid-code-code-sgid-code-processes"></a><code>SUID</code>/<code>SGID</code> processes</h2>
<div class="sectionbody">
<div class="paragraph">
<p>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 <code>SUID</code> 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
<code>SGID</code> bit, the effective group ID is set to
the group of the executable file.</p>
</div>
<div class="paragraph">
<p>Linux supports <strong>fscaps</strong>, which can grant
additional capabilities to a process in a finer-grained manner.
Additional mechanisms can be provided by loadable security
modules.</p>
</div>
<div class="paragraph">
<p>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.</p>
</div>
<div class="sect2">
<h3 id="sect-Defensive_Coding-Tasks-secure_getenv"><a class="anchor" href="#sect-Defensive_Coding-Tasks-secure_getenv"></a>Accessing Environment Variables</h3>
<div class="paragraph">
<p>The following steps are required so that a program does not
accidentally pick up untrusted data from environment
variables.</p>
</div>
<div class="ulist">
<ul>
<li>
<p>Compile your C/C++ sources with <code>-D_GNU_SOURCE</code>.
The Autoconf macro <code>AC_GNU_SOURCE</code> ensures this.</p>
</li>
<li>
<p>Check for the presence of the <code>secure_getenv</code>
and <code><em>secure_getenv</code> function. The Autoconf
directive <code>AC_CHECK_FUNCS([</em>secure_getenv secure_getenv])</code>
performs these checks.</p>
</li>
<li>
<p>Arrange for a proper definition of the
<code>secure_getenv</code> function. See <a href="#ex-Defensive_Coding-Tasks-secure_getenv">Obtaining a definition for <code>secure_getenv</code></a>.</p>
</li>
<li>
<p>Use <code>secure_getenv</code> instead of
<code>getenv</code> to obtain the value of critical
environment variables. <code>secure_getenv</code>
will pretend the variable has not bee set if the process
environment is not trusted.</p>
</li>
</ul>
</div>
<div class="paragraph">
<p>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.</p>
</div>
<div class="paragraph">
<p>Either the <code>secure_getenv</code> function or the
<code>__secure_getenv</code> is available from GNU libc.</p>
</div>
<div id="ex-Defensive_Coding-Tasks-secure_getenv" class="exampleblock">
<div class="title">Example 1. Obtaining a definition for <code>secure_getenv</code></div>
<div class="content">
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code data-lang="c"><span style="color:#579">#include</span> <span style="color:#B44;font-weight:bold">&lt;stdlib.h&gt;</span>
<span style="color:#579">#ifndef</span> HAVE_SECURE_GETENV
<span style="color:#579"># ifdef</span> HAVE__SECURE_GETENV
<span style="color:#579"># define</span> secure_getenv __secure_getenv
<span style="color:#579"># else</span>
<span style="color:#579"># error</span> neither secure_getenv nor __secure_getenv are available
<span style="color:#579"># endif</span>
<span style="color:#579">#endif</span></code></pre>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="sect-Defensive_Coding-Tasks-Processes-Daemons"><a class="anchor" href="#sect-Defensive_Coding-Tasks-Processes-Daemons"></a>Daemons</h2>
<div class="sectionbody">
<div class="paragraph">
<p>Background processes providing system services
(<strong>daemons</strong>) need to decouple themselves from
the controlling terminal and the parent process environment:</p>
</div>
<div class="ulist">
<ul>
<li>
<p>Fork.</p>
</li>
<li>
<p>In the child process, call <code>setsid</code>. The
parent process can simply exit (using
<code>_exit</code>, to avoid running clean-up
actions twice).</p>
</li>
<li>
<p>In the child process, fork again. Processing continues in
the child process. Again, the parent process should just
exit.</p>
</li>
<li>
<p>Replace the descriptors 0, 1, 2 with a descriptor for
<code>/dev/null</code>. Logging should be
redirected to <strong class="application">syslog</strong>.</p>
</li>
</ul>
</div>
<div class="paragraph">
<p>Older instructions for creating daemon processes recommended a
call to <code>umask(0)</code>. 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 <strong>umask</strong> needs setting, a restrictive
value such as <code>027</code> or <code>077</code>
is recommended.</p>
</div>
<div class="paragraph">
<p>Other aspects of the process environment may have to changed as
well (environment variables, signal handler disposition).</p>
</div>
<div class="paragraph">
<p>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
<strong class="application">systemd</strong>). 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.</p>
</div>
</div>
</div>
<div class="sect1">
<h2 id="semantics-of-command-line-arguments"><a class="anchor" href="#semantics-of-command-line-arguments"></a>Semantics of Command-line Arguments</h2>
<div class="sectionbody">
<div class="paragraph">
<p>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,
<strong class="application">python</strong> with the
<code class="option">-c</code> option).</p>
</div>
<div class="paragraph">
<p>Similar concerns apply to environment variables, the contents
of the current directory and its subdirectories.</p>
</div>
<div class="paragraph">
<p>Consequently, careful analysis is required if it is safe to
pass untrusted data to another program.</p>
</div>
</div>
</div>
<div class="sect1">
<h2 id="sect-Defensive_Coding-Tasks-Processes-Fork-Parallel"><a class="anchor" href="#sect-Defensive_Coding-Tasks-Processes-Fork-Parallel"></a><code>fork</code> as a Primitive for Parallelism</h2>
<div class="sectionbody">
<div class="paragraph">
<p>A call to <code>fork</code> which is not immediately
followed by a call to <code>execve</code> (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 <code>fork</code>
should be replaced with proper child processes or threads.</p>
</div>
</div>
</div>
</div>
</div>
</div>
<div id="bottom" class="text-muted py-3" >
<div class="foot">
<div class="container">
<div class="row footerlinks">
<div class="col-sm-3 col-xs-6 widget">
<h3 class="widget-title">About</h3>
<div class="widget-body">
<dl>
<dd><a href="https://fedoraproject.org/wiki/Overview">About Fedora</a></dd>
<dd><a href="https://getfedora.org/en/sponsors">Sponsors</a></dd>
<dd><a href="https://fedoramagazine.org">Fedora Magazine</a></dd>
<dd><a href="https://fedoraproject.org/wiki/Legal:Main#Legal">Legal</a></dd>
</dl>
<ul class="list-inline">
<li>
<a href="https://www.facebook.com/TheFedoraProject" class="btn-social btn-outline"><i class="fa fa-fw fa-facebook"></i></a>
</li>
<li>
<a href="https://plus.google.com/112917221531140868607" class="btn-social btn-outline"><i class="fa fa-fw fa-google-plus"></i></a>
</li>
<li>
<a href="https://twitter.com/fedora" class="btn-social btn-outline"><i class="fa fa-fw fa-twitter"></i></a>
</li>
</ul>
</div>
</div>
<div class="col-sm-3 col-xs-6 widget">
<h3 class="widget-title uppercase">Download</h3>
<div class="widget-body">
<dl>
<dd><a href="https://getfedora.org/en/workstation/download">Get Fedora Workstation</a></dd>
<dd><a href="https://getfedora.org/en/server/download">Get Fedora Server</a></dd>
<dd><a href="https://getfedora.org/en/atomic/download">Get Fedora Atomic</a></dd>
<dd><a href="https://spins.fedoraproject.org">Fedora Spins</a></dd>
<dd><a href="https://labs.fedoraproject.org">Fedora Labs</a></dd>
<dd><a href="https://arm.fedoraproject.org">Fedora ARM<span class="sup">&reg;</span></a></dd>
<dd><a href="https://alt.fedoraproject.org/">Alternative Downloads</a></dd>
</dl>
</div>
</div>
<div class="col-sm-3 col-xs-6 widget">
<h3 class="widget-title">Support</h3>
<div class="widget-body">
<dl>
<dd><a href="https://fedoraproject.org/wiki/Communicating_and_getting_help">Get Help</a></dd>
<dd><a href="https://ask.fedoraproject.org/">Ask Fedora</a></dd>
<dd><a href="https://fedoraproject.org/wiki/Common_F27_bugs">Common Bugs</a></dd>
<dd><a href="https://developer.fedoraproject.org/">Fedora Developer Portal</a></dd>
<dd><a href="https://docs.fedoraproject.org/f27/install-guide/index.html">Installation Guide</a></dd>
</dl>
</div>
</div>
<div class="col-sm-3 col-xs-6 widget">
<h3 class="widget-title">Join</h3>
<div class="widget-body">
<dl>
<dd><a href="https://fedoraproject.org/wiki/Join">Join Fedora</a></dd>
<dd><a href="http://fedoraplanet.org">Planet Fedora</a></dd>
<dd><a href="https://fedoraproject.org/wiki/SIGs">Fedora SIGs</a></dd>
<dd><a href="https://admin.fedoraproject.org/accounts/">Fedora Account System</a></dd>
<dd><a href="https://fedoracommunity.org/">Fedora Community</a></dd>
</dl>
</div>
</div>
</div> <!-- /row of widgets -->
<div class="row">
<div class="col-md-2">
<div class="widget-body">
<a href="https://www.redhat.com/"><img class="rh-logo" src="../../../master/_images/redhat-logo.png" alt="Red Hat Logo" /></a>
</div>
</div>
<div class="col-md-7">
<div class="widget-body">
<p class="sponsor">Fedora is sponsored by Red Hat.</p>
<p class="sponsor"><a href="https://www.redhat.com/en/technologies/linux-platforms/articles/relationship-between-fedora-and-rhel">Learn more about the relationship between Red Hat and Fedora &raquo;</a></p>
<p class="copy">&copy; 2017 Red Hat, Inc. and others. Please send any comments or corrections to the <a href="https://pagure.io/fedora-docs/docs-fp-o">documentation team</a></p>
</div>
</div>
</div> <!-- /row of widgets -->
</div>
</div>
</div>
<!-- jQuery (necessary for Bootstrap's JavaScript plugins) -->
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>
<!-- Latest compiled and minified JavaScript -->
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/js/bootstrap.min.js"></script>
<script src="../../../master/_javascripts/bootstrap-offcanvas.js" type="text/javascript"></script>
<script type="text/javascript">
/*<![CDATA[*/
$(document).ready(function() {
$("[id^='topicGroup']").on('show.bs.collapse', function (event) {
if (!($(event.target).attr('id').match(/^topicSubGroup/))) {
$(this).parent().find("[id^='tgSpan']").toggleClass("fa-angle-right fa-angle-down");
}
});
$("[id^='topicGroup']").on('hide.bs.collapse', function (event) {
if (!($(event.target).attr('id').match(/^topicSubGroup/))) {
$(this).parent().find("[id^='tgSpan']").toggleClass("fa-angle-right fa-angle-down");
}
});
$("[id^='topicSubGroup']").on('show.bs.collapse', function () {
$(this).parent().find("[id^='sgSpan']").toggleClass("fa-caret-right fa-caret-down");
});
$("[id^='topicSubGroup']").on('hide.bs.collapse', function () {
$(this).parent().find("[id^='sgSpan']").toggleClass("fa-caret-right fa-caret-down");
});
});
/*]]>*/
</script>
</body>
</html>

File diff suppressed because it is too large Load diff

View file

@ -1,472 +0,0 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta content="IE=edge" http-equiv="X-UA-Compatible">
<meta content="width=device-width, initial-scale=1.0" name="viewport">
<title>Defensive Coding Guide | Defensive Coding Guide | Specific Programming Tasks | Temporary Files</title>
<!-- Bootstrap -->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css">
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap-theme.min.css">
<!-- Overpass Font -->
<link rel="stylesheet" href="https://overpass-30e2.kxcdn.com/overpass.css">
<link href="../../../master/_stylesheets/asciibinder.css" rel="stylesheet" />
<!-- HTML5 shim and Respond.js for IE8 support of HTML5 elements and media queries -->
<!-- WARNING: Respond.js doesn't work if you view the page via file:// -->
<!--[if lt IE 9]>
<script src="https://oss.maxcdn.com/html5shiv/3.7.2/html5shiv.min.js"></script>
<script src="https://oss.maxcdn.com/respond/1.4.2/respond.min.js"></script>
<![endif]-->
<link href="../../../master/_images/favicon32x32.png" rel="shortcut icon" type="text/css">
<!--[if IE]><link rel="shortcut icon" href="../../../master/_images/favicon.ico"><![endif]-->
<meta content="AsciiBinder" name="application-name">
</head>
<body>
<div class="navbar navbar-default" role="navigation">
<div class="container-fluid">
<div class="navbar-header">
<a class="navbar-brand" href="https://docs.fedoraproject.org/"><img alt="Fedora Documentation" src="../../../master/_images/fedora.svg"></a>
</div>
</div>
</div>
<div class="container">
<p class="toggle-nav visible-xs pull-left">
<button class="btn btn-default btn-sm" type="button" data-toggle="offcanvas">Toggle nav</button>
</p>
<ol class="breadcrumb">
<li class="sitename">
<a href="../../../index.html">Home</a>
</li>
<li class="hidden-xs active">
<a href="../../en-US/index.html">Defensive Coding Guide </a>
</li>
<li class="hidden-xs active">
<a href="../../en-US/index.html">Defensive Coding Guide</a>
</li>
<li class="hidden-xs active"><a href="../../en-US/tasks/Tasks-Library_Design.html">Specific Programming Tasks</a></li>
<li class="hidden-xs active">
Temporary Files
</li>
</ol>
<div class="row row-offcanvas row-offcanvas-left">
<div class="col-xs-8 col-sm-3 col-md-3 sidebar sidebar-offcanvas">
<ul class="nav nav-sidebar">
<li class="nav-header">
<a class="" href="#" data-toggle="collapse" data-target="#topicGroup0">
<span id="tgSpan0" class="fa fa-angle-down"></span>Defensive Coding Guide
</a>
<ul id="topicGroup0" class="collapse in list-unstyled">
<li><a class="" href="../../en-US/index.html">Book Information</a></li>
<li class="nav-header">
<a class="" href="#" data-toggle="collapse" data-target="#topicSubGroup-0-1">
<span id="sgSpan-0-1" class="fa fa-caret-right"></span>&nbsp;Programming Languages
</a>
<ul id="topicSubGroup-0-1" class="nav-tertiary list-unstyled collapse">
<li><a class="" href="../../en-US/programming-languages/C.html">The C Programming Language</a></li>
<li><a class="" href="../../en-US/programming-languages/CXX.html">The C++ Programming&nbsp;Language</a></li>
<li><a class="" href="../../en-US/programming-languages/Java.html">The Java Programming Language</a></li>
<li><a class="" href="../../en-US/programming-languages/Python.html">The Python Programming Language</a></li>
<li><a class="" href="../../en-US/programming-languages/Shell.html">Shell Programming and bash</a></li>
<li><a class="" href="../../en-US/programming-languages/Go.html">The Go Programming Language</a></li>
<li><a class="" href="../../en-US/programming-languages/Vala.html">The Vala Programming Language</a></li>
</ul>
</li>
<li class="nav-header">
<a class="" href="#" data-toggle="collapse" data-target="#topicSubGroup-0-2">
<span id="sgSpan-0-2" class="fa fa-caret-down"></span>&nbsp;Specific Programming Tasks
</a>
<ul id="topicSubGroup-0-2" class="nav-tertiary list-unstyled collapse in">
<li><a class="" href="../../en-US/tasks/Tasks-Library_Design.html">Library Design</a></li>
<li><a class="" href="../../en-US/tasks/Tasks-Descriptors.html">File Descriptor Management</a></li>
<li><a class="" href="../../en-US/tasks/Tasks-File_System.html">File System Manipulation</a></li>
<li><a class=" active" href="../../en-US/tasks/Tasks-Temporary_Files.html">Temporary Files</a></li>
<li><a class="" href="../../en-US/tasks/Tasks-Processes.html">Processes</a></li>
<li><a class="" href="../../en-US/tasks/Tasks-Serialization.html">Serialization and Deserialization</a></li>
<li><a class="" href="../../en-US/tasks/Tasks-Cryptography.html">Cryptography</a></li>
<li><a class="" href="../../en-US/tasks/Tasks-Packaging.html">RPM Packaging</a></li>
</ul>
</li>
<li class="nav-header">
<a class="" href="#" data-toggle="collapse" data-target="#topicSubGroup-0-3">
<span id="sgSpan-0-3" class="fa fa-caret-right"></span>&nbsp;Implementing Security Features
</a>
<ul id="topicSubGroup-0-3" class="nav-tertiary list-unstyled collapse">
<li><a class="" href="../../en-US/features/Features-Authentication.html">Authentication and Authorization</a></li>
<li><a class="" href="../../en-US/features/Features-TLS.html">Transport Layer Security (TLS)</a></li>
<li><a class="" href="../../en-US/features/Features-HSM.html">Hardware Security Modules and Smart Cards</a></li>
</ul>
</li>
<li><a class="" href="../../en-US/Revision_History.html">Revision History</a></li>
</ul>
</li>
</ul>
</div>
<div class="col-xs-12 col-sm-9 col-md-9 main">
<div class="page-header">
<h2>Temporary Files</h2>
</div>
<div id="preamble">
<div class="sectionbody">
<div class="paragraph">
<p>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, <a href="#chap-Defensive_Coding-Tasks-File_System">[chap-Defensive_Coding-Tasks-File_System]</a>.</p>
</div>
<div class="paragraph">
<p>Secure creation of temporary files has four different aspects.</p>
</div>
<div class="ulist">
<ul>
<li>
<p>The location of the directory for temporary files must be
obtained in a secure manner (that is, untrusted environment
variables must be ignored, see <a href="#sect-Defensive_Coding-Tasks-secure_getenv">[sect-Defensive_Coding-Tasks-secure_getenv]</a>).</p>
</li>
<li>
<p>A new file must be created. Reusing an existing file must be
avoided (the <code>/tmp</code> race
condition). This is tricky because traditionally, system-wide
temporary directories shared by all users are used.</p>
</li>
<li>
<p>The file must be created in a way that makes it impossible for
other users to open it.</p>
</li>
<li>
<p>The descriptor for the temporary file should not leak to
subprocesses.</p>
</li>
</ul>
</div>
<div class="paragraph">
<p>All functions mentioned below will take care of these aspects.</p>
</div>
<div class="paragraph">
<p>Traditionally, temporary files are often used to reduce memory
usage of programs. More and more systems use RAM-based file
systems such as <code>tmpfs</code> 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.</p>
</div>
</div>
</div>
<div class="sect1">
<h2 id="chap-Defensive_Coding-Tasks-Temporary_Files-Location"><a class="anchor" href="#chap-Defensive_Coding-Tasks-Temporary_Files-Location"></a>Obtaining the Location of Temporary Directory</h2>
<div class="sectionbody">
<div class="paragraph">
<p>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:</p>
</div>
<div class="ulist">
<ul>
<li>
<p>Use <code>secure_getenv</code> to obtain the value
of the <code>TMPDIR</code> environment variable. If
it is set, convert the path to a fully-resolved absolute
path, using <code>realpath(path, NULL)</code>. Check
if the new path refers to a directory and is writeable. In
this case, use it as the temporary directory.</p>
</li>
<li>
<p>Fall back to <code>/tmp</code>.</p>
</li>
</ul>
</div>
<div class="paragraph">
<p>In Python, you can use the <code>tempfile.tempdir</code>
variable.</p>
</div>
<div class="paragraph">
<p>Java does not support SUID/SGID programs, so you can use the
<code>java.lang.System.getenv(String)</code> method to
obtain the value of the <code>TMPDIR</code> environment
variable, and follow the two steps described above. (Java&#8217;s
default directory selection does not honor
<code>TMPDIR</code>.)</p>
</div>
</div>
</div>
<div class="sect1">
<h2 id="named-temporary-files"><a class="anchor" href="#named-temporary-files"></a>Named Temporary Files</h2>
<div class="sectionbody">
<div class="paragraph">
<p>The <code>mkostemp</code> function creates a named
temporary file. You should specify the
<code>O_CLOEXEC</code> flag to avoid file descriptor leaks
to subprocesses. (Applications which do not use multiple threads
can also use <code>mkstemp</code>, but libraries should
use <code>mkostemp</code>.) For determining the
directory part of the file name pattern, see <a href="#chap-Defensive_Coding-Tasks-Temporary_Files-Location">Obtaining the Location of Temporary Directory</a>.</p>
</div>
<div class="paragraph">
<p>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 <code>mkostemp</code>
multiple times. Do not create additional file names derived
from the name provided by a previous
<code>mkostemp</code> call. However, it is safe to close
the descriptor returned by <code>mkostemp</code> and
reopen the file using the generated name.</p>
</div>
<div class="paragraph">
<p>The Python class <code>tempfile.NamedTemporaryFile</code>
provides similar functionality, except that the file is deleted
automatically by default. Note that you may have to use the
<code>file</code> attribute to obtain the actual file
object because some programming interfaces cannot deal with
file-like objects. The C function <code>mkostemp</code>
is also available as <code>tempfile.mkstemp</code>.</p>
</div>
<div class="paragraph">
<p>In Java, you can use the
<code>java.io.File.createTempFile(String, String,
File)</code> function, using the temporary file location
determined according to <a href="#chap-Defensive_Coding-Tasks-Temporary_Files-Location">Obtaining the Location of Temporary Directory</a>.
Do not use <code>java.io.File.deleteOnExit()</code> 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.</p>
</div>
</div>
</div>
<div class="sect1">
<h2 id="temporary-files-without-names"><a class="anchor" href="#temporary-files-without-names"></a>Temporary Files without Names</h2>
<div class="sectionbody">
<div class="paragraph">
<p>The <code>tmpfile</code> 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.</p>
</div>
<div class="paragraph">
<p>Alternatively, if the maximum size of the temporary file is
known beforehand, the <code>fmemopen</code> function can
be used to create a <code>FILE *</code> object which is
backed by memory.</p>
</div>
<div class="paragraph">
<p>In Python, unnamed temporary files are provided by the
<code>tempfile.TemporaryFile</code> class, and the
<code>tempfile.SpooledTemporaryFile</code> class provides
a way to avoid creation of small temporary files.</p>
</div>
<div class="paragraph">
<p>Java does not support unnamed temporary files.</p>
</div>
</div>
</div>
<div class="sect1">
<h2 id="chap-Defensive_Coding-Tasks-Temporary_Directory"><a class="anchor" href="#chap-Defensive_Coding-Tasks-Temporary_Directory"></a>Temporary Directories</h2>
<div class="sectionbody">
<div class="paragraph">
<p>The <code>mkdtemp</code> function can be used to create
a temporary directory. (For determining the directory part of
the file name pattern, see <a href="#chap-Defensive_Coding-Tasks-Temporary_Files-Location">Obtaining the Location of Temporary Directory</a>.)
The directory is not automatically removed. In Python, this
function is available as <code>tempfile.mkdtemp</code>.
In Java 7, temporary directories can be created using the
<code>java.nio.file.Files.createTempDirectory(Path, String,
FileAttribute&#8230;&#8203;)</code> function.</p>
</div>
<div class="paragraph">
<p>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
<strong>directory traversal</strong>).</p>
</div>
<div class="paragraph">
<p>Removing a directory tree in a completely safe manner is
complicated. Unless there are overriding performance concerns,
the <strong class="application">rm</strong> program should be used, with
the <code class="option">-rf</code> and <code class="option">--</code> options.</p>
</div>
</div>
</div>
<div class="sect1">
<h2 id="compensating-for-unsafe-file-creation"><a class="anchor" href="#compensating-for-unsafe-file-creation"></a>Compensating for Unsafe File Creation</h2>
<div class="sectionbody">
<div class="paragraph">
<p>There are two ways to make a function or program which excepts a
file name safe for use with temporary files. See
<a href="#sect-Defensive_Coding-Tasks-Processes-Creation">[sect-Defensive_Coding-Tasks-Processes-Creation]</a>,
for details on subprocess creation.</p>
</div>
<div class="ulist">
<ul>
<li>
<p>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 <a href="#chap-Defensive_Coding-Tasks-Temporary_Directory">Temporary Directories</a>.)</p>
</li>
<li>
<p>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:</p>
<div class="ulist">
<ul>
<li>
<p>The function or program must not create additional files
whose name is derived from the specified file name or
are otherwise predictable.</p>
</li>
<li>
<p>The function or program must not delete the file before
processing it.</p>
</li>
<li>
<p>It must not access any existing files in the same
directory.</p>
<div class="paragraph">
<p>It is often difficult to check whether these additional
assumptions are matched, therefore this approach is not
recommended.</p>
</div>
</li>
</ul>
</div>
</li>
</ul>
</div>
</div>
</div>
</div>
</div>
</div>
<div id="bottom" class="text-muted py-3" >
<div class="foot">
<div class="container">
<div class="row footerlinks">
<div class="col-sm-3 col-xs-6 widget">
<h3 class="widget-title">About</h3>
<div class="widget-body">
<dl>
<dd><a href="https://fedoraproject.org/wiki/Overview">About Fedora</a></dd>
<dd><a href="https://getfedora.org/en/sponsors">Sponsors</a></dd>
<dd><a href="https://fedoramagazine.org">Fedora Magazine</a></dd>
<dd><a href="https://fedoraproject.org/wiki/Legal:Main#Legal">Legal</a></dd>
</dl>
<ul class="list-inline">
<li>
<a href="https://www.facebook.com/TheFedoraProject" class="btn-social btn-outline"><i class="fa fa-fw fa-facebook"></i></a>
</li>
<li>
<a href="https://plus.google.com/112917221531140868607" class="btn-social btn-outline"><i class="fa fa-fw fa-google-plus"></i></a>
</li>
<li>
<a href="https://twitter.com/fedora" class="btn-social btn-outline"><i class="fa fa-fw fa-twitter"></i></a>
</li>
</ul>
</div>
</div>
<div class="col-sm-3 col-xs-6 widget">
<h3 class="widget-title uppercase">Download</h3>
<div class="widget-body">
<dl>
<dd><a href="https://getfedora.org/en/workstation/download">Get Fedora Workstation</a></dd>
<dd><a href="https://getfedora.org/en/server/download">Get Fedora Server</a></dd>
<dd><a href="https://getfedora.org/en/atomic/download">Get Fedora Atomic</a></dd>
<dd><a href="https://spins.fedoraproject.org">Fedora Spins</a></dd>
<dd><a href="https://labs.fedoraproject.org">Fedora Labs</a></dd>
<dd><a href="https://arm.fedoraproject.org">Fedora ARM<span class="sup">&reg;</span></a></dd>
<dd><a href="https://alt.fedoraproject.org/">Alternative Downloads</a></dd>
</dl>
</div>
</div>
<div class="col-sm-3 col-xs-6 widget">
<h3 class="widget-title">Support</h3>
<div class="widget-body">
<dl>
<dd><a href="https://fedoraproject.org/wiki/Communicating_and_getting_help">Get Help</a></dd>
<dd><a href="https://ask.fedoraproject.org/">Ask Fedora</a></dd>
<dd><a href="https://fedoraproject.org/wiki/Common_F27_bugs">Common Bugs</a></dd>
<dd><a href="https://developer.fedoraproject.org/">Fedora Developer Portal</a></dd>
<dd><a href="https://docs.fedoraproject.org/f27/install-guide/index.html">Installation Guide</a></dd>
</dl>
</div>
</div>
<div class="col-sm-3 col-xs-6 widget">
<h3 class="widget-title">Join</h3>
<div class="widget-body">
<dl>
<dd><a href="https://fedoraproject.org/wiki/Join">Join Fedora</a></dd>
<dd><a href="http://fedoraplanet.org">Planet Fedora</a></dd>
<dd><a href="https://fedoraproject.org/wiki/SIGs">Fedora SIGs</a></dd>
<dd><a href="https://admin.fedoraproject.org/accounts/">Fedora Account System</a></dd>
<dd><a href="https://fedoracommunity.org/">Fedora Community</a></dd>
</dl>
</div>
</div>
</div> <!-- /row of widgets -->
<div class="row">
<div class="col-md-2">
<div class="widget-body">
<a href="https://www.redhat.com/"><img class="rh-logo" src="../../../master/_images/redhat-logo.png" alt="Red Hat Logo" /></a>
</div>
</div>
<div class="col-md-7">
<div class="widget-body">
<p class="sponsor">Fedora is sponsored by Red Hat.</p>
<p class="sponsor"><a href="https://www.redhat.com/en/technologies/linux-platforms/articles/relationship-between-fedora-and-rhel">Learn more about the relationship between Red Hat and Fedora &raquo;</a></p>
<p class="copy">&copy; 2017 Red Hat, Inc. and others. Please send any comments or corrections to the <a href="https://pagure.io/fedora-docs/docs-fp-o">documentation team</a></p>
</div>
</div>
</div> <!-- /row of widgets -->
</div>
</div>
</div>
<!-- jQuery (necessary for Bootstrap's JavaScript plugins) -->
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>
<!-- Latest compiled and minified JavaScript -->
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/js/bootstrap.min.js"></script>
<script src="../../../master/_javascripts/bootstrap-offcanvas.js" type="text/javascript"></script>
<script type="text/javascript">
/*<![CDATA[*/
$(document).ready(function() {
$("[id^='topicGroup']").on('show.bs.collapse', function (event) {
if (!($(event.target).attr('id').match(/^topicSubGroup/))) {
$(this).parent().find("[id^='tgSpan']").toggleClass("fa-angle-right fa-angle-down");
}
});
$("[id^='topicGroup']").on('hide.bs.collapse', function (event) {
if (!($(event.target).attr('id').match(/^topicSubGroup/))) {
$(this).parent().find("[id^='tgSpan']").toggleClass("fa-angle-right fa-angle-down");
}
});
$("[id^='topicSubGroup']").on('show.bs.collapse', function () {
$(this).parent().find("[id^='sgSpan']").toggleClass("fa-caret-right fa-caret-down");
});
$("[id^='topicSubGroup']").on('hide.bs.collapse', function () {
$(this).parent().find("[id^='sgSpan']").toggleClass("fa-caret-right fa-caret-down");
});
});
/*]]>*/
</script>
</body>
</html>

View file

@ -1,598 +0,0 @@
@import url(https://maxcdn.bootstrapcdn.com/font-awesome/4.1.0/css/font-awesome.min.css);
/* ------------------------------------------------------------
Image: "Spin" https://www.flickr.com/photos/eflon/3655695161/
Author: eflon https://www.flickr.com/photos/eflon/
License: https://creativecommons.org/licenses/by/2.0/
---------------------------------------------------------------*/
.attribution {
text-align: center;
position: relative;
bottom: -20px;
}
.attribution .btn {
color: #808080;
color: rgba(175,175,175, .65);
font-size: 11px;
}
.attribution .btn:hover {
text-decoration: none;
color: #aaa;
}
.popover-content {
font-size: 12px;
line-height: 1.3;
font-weight: normal;
}
@media screen and (max-width: 980px) {
body {
margin-bottom: 200px;
}
footer {
text-align: center;
}
footer .text-right {
text-align: center !important;
}
#footer_social .first {
margin-left: 0;
}
#footer_social > a {
top: 24px;
}
}
.fa-inverse:hover {
color: #ccc;
}
.collapse a.active {
background-color: #DEEAF4;
color: #000;
position: relative;
}
.collapse a.active:hover {
text-decoration: none;
}
.collapse a.active:before {
background-color: #A0C3E5;
content: "";
display: inline-block;
height: 100%;
left: 0;
position: absolute;
top: 0;
width: 3px;
}
.main h2, .main .h2 {
border-top: 0px;
padding-top: 10px;
font-size: 28px;
}
.page-header {
height: 100% !important;
}
.page-header .img-responsive {
display: inline;
}
.page-header h2 {
font-size: 32px;
display: inline;
vertical-align: bottom;
}
.navbar-brand {
padding: initial;
height: initial;
padding: 12px;
}
.navbar-header h2 {
display: inline;
position: absolute;
font-weight: bold;
margin-top: 50px ;
}
.nav > li > a.hover{
background-color: none;
}
h1, h2, h3, h4, h5, h6, .h1, .h2, .h3, .h4, .h5, .h6 {
position: relative;
}
h2 > a.anchor, h3 > a.anchor, h4 > a.anchor, h5 > a.anchor, h6 > a.anchor {
display: block;
font-weight: normal;
margin-left: -1.5ex;
position: absolute;
text-align: center;
text-decoration: none !important;
visibility: hidden;
width: 1.5ex;
z-index: 1001;
}
h2 > a.anchor:before, h3 > a.anchor:before, h4 > a.anchor:before, h5 > a.anchor:before, h6 > a.anchor:before {
content: "\f0c1";
display: block;
font-family: FontAwesome;
font-size: 0.7em;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
padding-top: 0.2em;
}
h4 > a.anchor:before, h5 > a.anchor:before, h6 > a.anchor:before {
font-size: 1em;
}
h2:hover > a.anchor,
h2 > a.anchor:hover,
h3:hover > a.anchor,
h3 > a.anchor:hover,
h4:hover > a.anchor,
h4 > a.anchor:hover,
h5:hover > a.anchor,
h5 > a.anchor:hover,
h6:hover > a.anchor,
h6 > a.anchor:hover {
visibility: visible;
}
.main {
border-left: 1px solid #e7e7e7;
margin-left: -1px;
padding-left: 25px;
}
@media (min-width: 768px) {
.main {
padding-left: 30px;
}
}
/*
* Sidebar
*/
.nav-header {
font-size: 16px;
}
.nav-header ul {
font-size: 14px;
}
.nav-header ul li a {
display: block;
padding: 5px 20px 5px 25px;
font-size: 13px;
font-weight: normal;
}
.nav-sidebar .fa {
text-align: center;
top: -1px;
width: 14px;
}
.nav-sidebar li a {
color: inherit;
}
.nav-sidebar li a:hover {
color: #000;
}
.nav-sidebar ul li ul.nav-tertiary li a {
padding-left: 50px;
}
.nav-sidebar > li > a {
padding: 7px 0;
}
.nav-sidebar > li > a:focus, .nav-sidebar > li > a:hover {
background: transparent;
}
.sidebar {
font-weight: 300;
display: none;
padding-top: 13px;
}
@media screen and (max-width: 767px) {
.sidebar {
padding-left: 30px;
padding-right: 0;
}
}
@media screen and (min-width: 768px) {
.sidebar {
border-right: 1px solid #e7e7e7;
display: block;
}
}
/*
* Off Canvas
* --------------------------------------------------
*/
body, html {
overflow-x: hidden; /* Prevent scroll on narrow devices */
font-family: "Overpass", sans-serif;
}
.toggle-nav {
margin-right: 20px;
}
@media screen and (max-width: 767px) {
.row-offcanvas {
position: relative;
-webkit-transition: all .25s ease-out;
-o-transition: all .25s ease-out;
transition: all .25s ease-out;
}
.row-offcanvas-right {
right: 0;
}
.row-offcanvas-left {
left: 0;
}
.row-offcanvas-right
.sidebar-offcanvas {
right: -75%; /* 8 columns */
}
.row-offcanvas-left
.sidebar-offcanvas {
left: -75%; /* 8 columns */
}
.row-offcanvas-right.active {
right: 75%; /* 8 columns */
}
.row-offcanvas-left.active {
left: 75%; /* 8 columns */
}
.sidebar-offcanvas {
overflow: hidden;
position: absolute;
top: 0;
width: 75%; /* 8 columns */
}
}
p {
margin: 0 0 1.6em;
}
/* Remnants of Asciidoctor default stylesheet - remove styles as needed */
#map_canvas img, #map_canvas embed, #map_canvas object, .map_canvas img, .map_canvas embed, .map_canvas object { max-width: none !important; }
.left { float: left !important; }
.right { float: right !important; }
.text-left { text-align: left !important; }
.text-right { text-align: right !important; }
.text-center { text-align: center !important; }
.text-justify { text-align: justify !important; }
.hide { display: none; }
.subheader, #content #toctitle, .admonitionblock td.content > .title, .audioblock > .title, .exampleblock > .title, .imageblock > .title, .listingblock > .title, .literalblock > .title, .stemblock > .title, .openblock > .title, .paragraph > .title, .quoteblock > .title, table.tableblock > .title, .verseblock > .title, .videoblock > .title, .dlist > .title, .olist > .title, .ulist > .title, .qlist > .title, .hdlist > .title { line-height: 1.4; color: #7a2518; font-weight: 300; margin-top: 0.2em; margin-bottom: 0.5em; }
abbr, acronym { text-transform: uppercase; font-size: 90%; color: #333333; border-bottom: 1px dotted #dddddd; cursor: help; }
abbr { text-transform: none; }
blockquote { margin: 0 0 1.25em; padding: 0.5625em 1.25em 0 1.1875em; border-left: 3px solid #487c58; }
blockquote cite { display: block; font-size: inherit; color: #454545; }
blockquote cite:before { content: "\2014 \0020"; }
blockquote cite a, blockquote cite a:visited { color: #454545; }
blockquote, blockquote p { line-height: 1.6; color: #6e6e6e; }
@media only screen and (min-width: 768px) {
#toctitle, .sidebarblock > .content > .title { line-height: 1.4; }
#toctitle, .sidebarblock > .content > .title { font-size: 1.6875em; }
}
table { background: white; margin-bottom: 1.25em; border: solid 1px #dddddd; }
table thead, table tfoot { background: whitesmoke; font-weight: bold; }
table thead tr th, table thead tr td, table tfoot tr th, table tfoot tr td { padding: 0.5em 0.625em 0.625em; font-size: inherit; color: #333333; text-align: left; }
table tr th, table tr td { padding: 0.5625em 0.625em; font-size: inherit; color: #333333; }
table tr.even, table tr.alt, table tr:nth-of-type(even) { background: #f9f9f9; }
table thead tr th, table tfoot tr th, table tbody tr td, table tr td, table tfoot tr td { display: table-cell; line-height: 1.6; }
.clearfix:before, .clearfix:after, .float-group:before, .float-group:after { content: " "; display: table; }
.clearfix:after, .float-group:after { clear: both; }
*:not(pre) > code { font-size: inherit; padding: 0; white-space: nowrap; background-color: inherit; border: 0 solid #dddddd; -webkit-border-radius: 4px; border-radius: 4px; text-shadow: none; line-height: 1; }
.keyseq { color: #666666; }
kbd:not(.keyseq) { display: inline-block; color: #333333; font-size: 0.75em; line-height: 1.4; background-color: #f7f7f7; border: 1px solid #ccc; -webkit-border-radius: 3px; border-radius: 3px; -webkit-box-shadow: 0 1px 0 rgba(0, 0, 0, 0.2), 0 0 0 2px white inset; box-shadow: 0 1px 0 rgba(0, 0, 0, 0.2), 0 0 0 2px white inset; margin: -0.15em 0.15em 0 0.15em; padding: 0.2em 0.6em 0.2em 0.5em; vertical-align: middle; white-space: nowrap; }
.keyseq kbd:first-child { margin-left: 0; }
.keyseq kbd:last-child { margin-right: 0; }
.menuseq, .menu { color: #1a1a1a; }
b.button:before, b.button:after { position: relative; top: -1px; font-weight: normal; }
b.button:before { content: "["; padding: 0 3px 0 2px; }
b.button:after { content: "]"; padding: 0 2px 0 3px; }
p a > code:hover { color: #561309; }
#header, #content, #footnotes, #footer { width: 100%; margin-left: auto; margin-right: auto; margin-top: 0; margin-bottom: 0; max-width: 62.5em; *zoom: 1; position: relative; padding-left: 0.9375em; padding-right: 0.9375em; }
#header:before, #header:after, #content:before, #content:after, #footnotes:before, #footnotes:after, #footer:before, #footer:after { content: " "; display: table; }
#header:after, #content:after, #footnotes:after, #footer:after { clear: both; }
#content:before { content: none; }
#header { margin-bottom: 2.5em; }
#header > h1 { color: black; font-weight: 300; border-bottom: 1px solid #d8d8d8; margin-bottom: -28px; padding-bottom: 32px; }
#header span { color: #6e6e6e; }
#header #revnumber { text-transform: capitalize; }
#header br { display: none; }
#header br + span { padding-left: 3px; }
#header br + span:before { content: "\2013 \0020"; }
#header br + span.author { padding-left: 0; }
#header br + span.author:before { content: ", "; }
#toc { border-bottom: 3px double #e5e5e5; padding-top: 1em; padding-bottom: 1.25em; }
#toc > ul { margin-left: 0.25em; }
#toc ul.sectlevel0 > li > a { font-style: italic; }
#toc ul.sectlevel0 ul.sectlevel1 { margin-left: 0; margin-top: 0.5em; margin-bottom: 0.5em; }
#toc ul { font-family: "Open Sans", "DejaVu Sans", "Sans", sans-serif; list-style-type: none; }
#toc a { text-decoration: none; }
#toc a:active { text-decoration: underline; }
#toctitle { color: #7a2518; }
@media only screen and (min-width: 768px) { body.toc2 { padding-left: 15em; padding-right: 0; }
#toc.toc2 { background-color: #fafaf9; position: fixed; width: 15em; left: 0; top: 0; border-right: 1px solid #e5e5e5; border-bottom: 0; z-index: 1000; padding: 1.25em 1em; height: 100%; overflow: auto; }
#toc.toc2 #toctitle { margin-top: 0; font-size: 1.2em; }
#toc.toc2 > ul { font-size: .90em; margin-bottom: 0; }
#toc.toc2 ul ul { margin-left: 0; padding-left: 1em; }
#toc.toc2 ul.sectlevel0 ul.sectlevel1 { padding-left: 0; margin-top: 0.5em; margin-bottom: 0.5em; }
body.toc2.toc-right { padding-left: 0; padding-right: 15em; }
body.toc2.toc-right #toc.toc2 { border-right: 0; border-left: 1px solid #e5e5e5; left: auto; right: 0; } }
@media only screen and (min-width: 1280px) { body.toc2 { padding-left: 20em; padding-right: 0; }
#toc.toc2 { width: 20em; }
#toc.toc2 #toctitle { font-size: 1.375em; }
#toc.toc2 > ul { font-size: 0.95em; }
#toc.toc2 ul ul { padding-left: 1.25em; }
body.toc2.toc-right { padding-left: 0; padding-right: 20em; } }
#content #toc { border-style: solid; border-width: 1px; border-color: #e3e3dd; margin-bottom: 1.25em; padding: 1.25em; background: #fafaf9; border-width: 0; -webkit-border-radius: 4px; border-radius: 4px; }
#content #toc > :first-child { margin-top: 0; }
#content #toc > :last-child { margin-bottom: 0; }
#content #toctitle { font-size: 1.375em; }
#footer { max-width: 100%; background-color: #333333; padding: 1.25em; }
#footer-text { color: #cccccc; line-height: 1.44; }
.audioblock, .imageblock, .literalblock, .listingblock, .stemblock, .verseblock, .videoblock { margin-bottom: 2.5em; }
.admonitionblock td.content > .title, .audioblock > .title, .exampleblock > .title, .imageblock > .title, .listingblock > .title, .literalblock > .title, .stemblock > .title, .openblock > .title, .paragraph > .title, .quoteblock > .title, table.tableblock > .title, .verseblock > .title, .videoblock > .title, .dlist > .title, .olist > .title, .ulist > .title, .qlist > .title, .hdlist > .title { text-rendering: optimizeLegibility; text-align: left; font-family: "Noto Serif", "DejaVu Serif", "Serif", serif; font-weight: normal; font-style: italic; }
table.tableblock > caption.title { white-space: nowrap; overflow: visible; max-width: 0; }
table.tableblock #preamble > .sectionbody > .paragraph:first-of-type p { font-size: inherit; }
.admonitionblock > table { border: 0; background: none; width: 100%; }
.admonitionblock > table td.icon { text-align: center; width: 80px; }
.admonitionblock > table td.icon img { max-width: none; }
.admonitionblock > table td.icon .title { font-weight: 300; text-transform: uppercase; }
.admonitionblock > table td.content { padding-left: 0; padding-right: 1.25em; color: #6e6e6e; }
.admonitionblock > table td.content > :last-child > :last-child { margin-bottom: 0; }
.exampleblock > .content { border-style: solid; border-width: 1px; border-color: #e6e6e6; margin-bottom: 1.25em; padding: 1.25em; background: white; -webkit-border-radius: 4px; border-radius: 4px; }
.exampleblock > .content > :first-child { margin-top: 0; }
.exampleblock > .content > :last-child { margin-bottom: 0; }
.exampleblock > .content h1, .exampleblock > .content h2, .exampleblock > .content h3, .exampleblock > .content #toctitle, .sidebarblock.exampleblock > .content > .title, .exampleblock > .content h4, .exampleblock > .content h5, .exampleblock > .content h6, .exampleblock > .content p { color: #333333; }
.exampleblock > .content h1, .exampleblock > .content h2, .exampleblock > .content h3, .exampleblock > .content #toctitle, .sidebarblock.exampleblock > .content > .title, .exampleblock > .content h4, .exampleblock > .content h5, .exampleblock > .content h6 { line-height: 1; margin-bottom: 0.625em; }
.exampleblock > .content h1.subheader, .exampleblock > .content h2.subheader, .exampleblock > .content h3.subheader, .exampleblock > .content .subheader#toctitle, .sidebarblock.exampleblock > .content > .subheader.title, .exampleblock > .content h4.subheader, .exampleblock > .content h5.subheader, .exampleblock > .content h6.subheader { line-height: 1.4; }
.exampleblock.result > .content { -webkit-box-shadow: 0 1px 8px #e3e3dd; box-shadow: 0 1px 8px #e3e3dd; }
.sidebarblock { border-style: solid; border-width: 1px; border-color: #e3e3dd; margin-top: -1.0em; margin-bottom: 1.6em; margin-left: 1em; padding: .5em; background: #F1F3F5; -webkit-border-radius: 4px; border-radius: 4px; overflow-x: auto; float: right; width: 40%; }
.sidebarblock > :first-child { margin-top: 0; }
.sidebarblock > :last-child { margin-bottom: 0; }
.sidebarblock h1, .sidebarblock h2, .sidebarblock h3, .sidebarblock #toctitle, .sidebarblock > .content > .title, .sidebarblock h4, .sidebarblock h5, .sidebarblock h6, .sidebarblock p { color: #333333; }
.sidebarblock h1, .sidebarblock h2, .sidebarblock h3, .sidebarblock #toctitle, .sidebarblock > .content > .title, .sidebarblock h4, .sidebarblock h5, .sidebarblock h6 { line-height: 1; margin-bottom: 0.625em; }
.sidebarblock h1.subheader, .sidebarblock h2.subheader, .sidebarblock h3.subheader, .sidebarblock .subheader#toctitle, .sidebarblock > .content > .subheader.title, .sidebarblock h4.subheader, .sidebarblock h5.subheader, .sidebarblock h6.subheader { line-height: 1.4; }
.sidebarblock > .content > .title { color: inherit; font-size: 28px; font-weight: 500; margin-top: 0; line-height: 1.6; }
.width50 { width: 50% ! important}
.exampleblock > .content > :last-child > :last-child, .exampleblock > .content .olist > ol > li:last-child > :last-child, .exampleblock > .content .ulist > ul > li:last-child > :last-child, .exampleblock > .content .qlist > ol > li:last-child > :last-child, .sidebarblock > .content > :last-child > :last-child, .sidebarblock > .content .olist > ol > li:last-child > :last-child, .sidebarblock > .content .ulist > ul > li:last-child > :last-child, .sidebarblock > .content .qlist > ol > li:last-child > :last-child { margin-bottom: 0; }
.literalblock pre, .literalblock pre[class], .listingblock pre, .listingblock pre[class] { border: 0px; background-color: #F0F3F5; -webkit-border-radius: 5px; border-radius: 5px; padding: 1.5em 2.5em; word-wrap: break-word; }
.literalblock pre.nowrap, .literalblock pre[class].nowrap, .listingblock pre.nowrap, .listingblock pre[class].nowrap { overflow-x: auto; white-space: pre; word-wrap: normal; }
.literalblock pre > code, .literalblock pre[class] > code, .listingblock pre > code, .listingblock pre[class] > code { display: block; }
.listingblock > .content { position: relative; }
.listingblock:hover code[class*=" language-"]:before { text-transform: uppercase; font-size: 0.9em; color: #999; position: absolute; top: 0.375em; right: 0.375em; }
.listingblock:hover code.asciidoc:before { content: "asciidoc"; }
.listingblock:hover code.clojure:before { content: "clojure"; }
.listingblock:hover code.css:before { content: "css"; }
.listingblock:hover code.go:before { content: "go"; }
.listingblock:hover code.groovy:before { content: "groovy"; }
.listingblock:hover code.html:before { content: "html"; }
.listingblock:hover code.java:before { content: "java"; }
.listingblock:hover code.javascript:before { content: "javascript"; }
.listingblock:hover code.python:before { content: "python"; }
.listingblock:hover code.ruby:before { content: "ruby"; }
.listingblock:hover code.sass:before { content: "sass"; }
.listingblock:hover code.scss:before { content: "scss"; }
.listingblock:hover code.xml:before { content: "xml"; }
.listingblock:hover code.yaml:before { content: "yaml"; }
.listingblock.terminal pre .command:before { content: attr(data-prompt); padding-right: 0.5em; color: #999; }
.listingblock.terminal pre .command:not([data-prompt]):before { content: '$'; }
table.pyhltable { border: 0; margin-bottom: 0; }
table.pyhltable td { vertical-align: top; padding-top: 0; padding-bottom: 0; }
table.pyhltable td.code { padding-left: .75em; padding-right: 0; }
.highlight.pygments .lineno, table.pyhltable td:not(.code) { color: #999; padding-left: 0; padding-right: .5em; border-right: 1px solid #d8d8d8; }
.highlight.pygments .lineno { display: inline-block; margin-right: .25em; }
table.pyhltable .linenodiv { background-color: transparent !important; padding-right: 0 !important; }
.quoteblock { margin: 0 0 1.25em 0; padding: 0.5625em 1.25em 0 1.1875em; border-left: 3px solid #487c58; }
.quoteblock blockquote { margin: 0 0 1.25em 0; padding: 0 0 0.625em 0; border: 0; }
.quoteblock blockquote > .paragraph:last-child p { margin-bottom: 0; }
.quoteblock .attribution { margin-top: -0.625em; padding-bottom: 0.625em; font-size: inherit; color: #454545; line-height: 1.6; }
.quoteblock .attribution br { display: none; }
.quoteblock .attribution cite { display: block; }
table.tableblock { max-width: 100%; }
table.tableblock td .paragraph:last-child p > p:last-child, table.tableblock th > p:last-child, table.tableblock td > p:last-child { margin-bottom: 0; }
table.spread { width: 100%; }
table.tableblock, th.tableblock, td.tableblock { border: 0 solid #dddddd; }
table.grid-all th.tableblock, table.grid-all td.tableblock { border-width: 0 1px 1px 0; }
table.grid-all tfoot > tr > th.tableblock, table.grid-all tfoot > tr > td.tableblock { border-width: 1px 1px 0 0; }
table.grid-cols th.tableblock, table.grid-cols td.tableblock { border-width: 0 1px 0 0; }
table.grid-all * > tr > .tableblock:last-child, table.grid-cols * > tr > .tableblock:last-child { border-right-width: 0; }
table.grid-rows th.tableblock, table.grid-rows td.tableblock { border-width: 0 0 1px 0; }
table.grid-all tbody > tr:last-child > th.tableblock, table.grid-all tbody > tr:last-child > td.tableblock, table.grid-all thead:last-child > tr > th.tableblock, table.grid-rows tbody > tr:last-child > th.tableblock, table.grid-rows tbody > tr:last-child > td.tableblock, table.grid-rows thead:last-child > tr > th.tableblock { border-bottom-width: 0; }
table.grid-rows tfoot > tr > th.tableblock, table.grid-rows tfoot > tr > td.tableblock { border-width: 1px 0 0 0; }
table.frame-all { border-width: 1px; }
table.frame-sides { border-width: 0 1px; }
table.frame-topbot { border-width: 1px 0; }
th.halign-left, td.halign-left { text-align: left; }
th.halign-right, td.halign-right { text-align: right; }
th.halign-center, td.halign-center { text-align: center; }
th.valign-top, td.valign-top { vertical-align: top; }
th.valign-bottom, td.valign-bottom { vertical-align: bottom; }
th.valign-middle, td.valign-middle { vertical-align: middle; }
table thead th, table tfoot th { font-weight: bold; }
tbody tr th { display: table-cell; line-height: 1.6; background: whitesmoke; }
tbody tr th, tbody tr th p, tfoot tr th, tfoot tr th p { color: #333333; font-weight: bold; }
td > div.verse { white-space: pre; }
ul.unstyled, ol.unnumbered, ul.checklist, ul.none { list-style-type: none; }
ul.unstyled, ol.unnumbered, ul.checklist { margin-left: 0.625em; }
ul.checklist li > p:first-child > .fa-check-square-o:first-child, ul.checklist li > p:first-child > input[type="checkbox"]:first-child { margin-right: 0.25em; }
ul.checklist li > p:first-child > input[type="checkbox"]:first-child { position: relative; top: 1px; }
ul.inline { margin: 0 auto 0.625em auto; margin-left: -1.375em; margin-right: 0; padding: 0; list-style: none; overflow: hidden; }
ul.inline > li { list-style: none; float: left; margin-left: 1.375em; display: block; }
ul.inline > li > * { display: block; }
.unstyled dl dt { font-weight: normal; font-style: normal; }
ol.arabic { list-style-type: decimal; }
ol.decimal { list-style-type: decimal-leading-zero; }
ol.loweralpha { list-style-type: lower-alpha; }
ol.upperalpha { list-style-type: upper-alpha; }
ol.lowerroman { list-style-type: lower-roman; }
ol.upperroman { list-style-type: upper-roman; }
ol.lowergreek { list-style-type: lower-greek; }
.hdlist > table, .colist > table { border: 0; background: none; }
.hdlist > table > tbody > tr, .colist > table > tbody > tr { background: none; }
td.hdlist1 { padding-right: .75em; font-weight: bold; }
td.hdlist1, td.hdlist2 { vertical-align: top; }
.literalblock + .colist, .listingblock + .colist { margin-top: -0.5em; }
.colist > table tr > td:first-of-type { padding: 0 .75em; line-height: 1; }
.colist > table tr > td:last-of-type { padding: 0.25em 0; }
.qanda > ol > li > p > em:only-child { color: #1d4b8f; }
.thumb, .th { line-height: 0; display: inline-block; border: solid 4px white; -webkit-box-shadow: 0 0 0 1px #dddddd; box-shadow: 0 0 0 1px #dddddd; }
.imageblock.left, .imageblock[style*="float: left"] { margin: 0.25em 0.625em 1.25em 0; }
.imageblock.right, .imageblock[style*="float: right"] { margin: 0.25em 0 1.25em 0.625em; }
.imageblock > .title { margin-bottom: 0; }
.imageblock.thumb, .imageblock.th { border-width: 6px; }
.imageblock.thumb > .title, .imageblock.th > .title { padding: 0 0.125em; }
.image.left, .image.right { margin-top: 0.25em; margin-bottom: 0.25em; display: inline-block; line-height: 0; }
.image.left { margin-right: 0.625em; }
.image.right { margin-left: 0.625em; }
a.image { text-decoration: none; }
span.footnote, span.footnoteref { vertical-align: super; font-size: 0.875em; }
span.footnote a, span.footnoteref a { text-decoration: none; }
span.footnote a:active, span.footnoteref a:active { text-decoration: underline; }
#footnotes { padding-top: 0.75em; padding-bottom: 0.75em; margin-bottom: 0.625em; }
#footnotes hr { width: 20%; min-width: 6.25em; margin: -.25em 0 .75em 0; border-width: 1px 0 0 0; }
#footnotes .footnote { padding: 0 0.375em; line-height: 1.3; font-size: 0.875em; margin-left: 1.2em; text-indent: -1.2em; margin-bottom: .2em; }
#footnotes .footnote a:first-of-type { font-weight: bold; text-decoration: none; }
#footnotes .footnote:last-of-type { margin-bottom: 0; }
#content #footnotes { margin-top: -0.625em; margin-bottom: 0; padding: 0.75em 0; }
.gist .file-data > table { border: none; background: #fff; width: 100%; margin-bottom: 0; }
.gist .file-data > table td.line-data { width: 99%; }
div.unbreakable { page-break-inside: avoid; }
.replaceable { font-style: italic; font-color: inherit; font-family: inherit; }
.parameter { font-style: italic; font-family: monospace; }
.userinput { font-weight: bold; font-family: monospace; }
.envar { font-weight: bold; font-family: monospace; font-size: 90%; }
.sysitem { font-weight: bold; font-size: 90%; }
.package { font-weight: bold; font-size: 90%; }
.filename { font-weight: bold; font-style: italic; font-size: 90%; }
.big { font-size: larger; }
.small { font-size: smaller; }
.underline { text-decoration: underline; }
.overline { text-decoration: overline; }
.line-through { text-decoration: line-through; }
.aqua { color: #00bfbf; }
.aqua-background { background-color: #00fafa; }
.black { color: black; }
.black-background { background-color: black; }
.blue { color: #0000bf; }
.blue-background { background-color: #0000fa; }
.fuchsia { color: #bf00bf; }
.fuchsia-background { background-color: #fa00fa; }
.gray { color: #606060; }
.gray-background { background-color: #7d7d7d; }
.green { color: #006000; }
.green-background { background-color: #007d00; }
.lime { color: #00bf00; }
.lime-background { background-color: #00fa00; }
.maroon { color: #600000; }
.maroon-background { background-color: #7d0000; }
.navy { color: #000060; }
.navy-background { background-color: #00007d; }
.olive { color: #606000; }
.olive-background { background-color: #7d7d00; }
.purple { color: #600060; }
.purple-background { background-color: #7d007d; }
.red { color: #bf0000; }
.red-background { background-color: #fa0000; }
.silver { color: #909090; }
.silver-background { background-color: #bcbcbc; }
.teal { color: #006060; }
.teal-background { background-color: #007d7d; }
.white { color: #bfbfbf; }
.white-background { background-color: #fafafa; }
.yellow { color: #bfbf00; }
.yellow-background { background-color: #fafa00; }
span.icon > .fa { cursor: default; }
.admonitionblock td.icon [class^="fa icon-"] { font-size: 2.5em; cursor: default; }
.admonitionblock td.icon .icon-note:before { content: "\f05a"; color: #4E9FDD; }
.admonitionblock td.icon .icon-tip:before { content: "\f0eb"; color: #2C8596; }
.admonitionblock td.icon .icon-warning:before { content: "\f071"; color: #ec7a08; }
.admonitionblock td.icon .icon-caution:before { content: "\f06d"; color: #ec7a08; }
.admonitionblock td.icon .icon-important:before { content: "\f06a"; color: #c00; }
.conum[data-value] { display: inline-block; color: white !important; background-color: #333333; -webkit-border-radius: 100px; border-radius: 100px; text-align: center; width: 20px; height: 20px; font-size: 12px; line-height: 20px; font-family: "Open Sans", "Sans", sans-serif; font-style: normal; font-weight: bold; text-indent: -1px; }
.conum[data-value] * { color: white !important; }
.conum[data-value] + b { display: none; }
.conum[data-value]:after { content: attr(data-value); }
pre .conum[data-value] { position: relative; top: -2px; }
b.conum * { color: inherit !important; }
.conum:not([data-value]):empty { display: none; }
.print-only { display: none !important; }
@media print { @page { margin: 1.25cm 0.75cm; }
* { -webkit-box-shadow: none !important; box-shadow: none !important; text-shadow: none !important; }
a, a:visited { color: inherit !important; text-decoration: underline !important; }
a[href^="http:"]:after, a[href^="https:"]:after { content: " (" attr(href) ")"; }
a[href^="#"], a[href^="#"]:visited, a[href^="mailto:"], a[href^="mailto:"]:visited { text-decoration: none !important; }
abbr[title]:after { content: " (" attr(title) ")"; }
pre, blockquote { page-break-inside: avoid; }
code { color: #191919; }
thead { display: table-header-group; }
tr, img { page-break-inside: avoid; }
img { max-width: 100% !important; }
p { orphans: 3; widows: 3; }
h2, h3, #toctitle, .sidebarblock > .content > .title, #toctitle, .sidebarblock > .content > .title { page-break-after: avoid; }
#toc, .sidebarblock { background: none !important; }
#toc { border-bottom: 1px solid #d8d8d8 !important; padding-bottom: 0 !important; }
.sect1 { padding-bottom: 0 !important; }
.sect1 + .sect1 { border: none !important; }
body.book #header { text-align: center; }
body.book #header > h1 { border: none !important; margin: 2.5em 0 1em 0; padding: 0; }
body.book #header span { line-height: 1.6; }
body.book #header br { display: block; }
body.book #header br + span { padding-left: 0; }
body.book #header br + span:before { content: none !important; }
body.book #toc { border: none !important; text-align: left !important; padding: 0 !important; }
#footer { background: none !important; }
#footer-text { color: #333333 !important; }
.hide-on-print { display: none !important; }
.print-only { display: block !important; }
.hide-for-print { display: none !important; }
.show-for-print { display: inherit !important; } }
.corner-ribbon{
width: 16em;
background: #3c6eb4 ;
position: absolute;
top: 3em;
right: -4em;
text-align: center;
line-height: 5ex;
color: #dedede;
transform: rotate(45deg);
-webkit-transform: rotate(45deg);
z-index: 999;
}
.corner-ribbon a { color: #FFFFFF; }

View file

@ -1,3 +0,0 @@
<%- Dir.glob("_stylesheets/*").sort.each do |sheet| -%>
<link href="<%= File.join(css_path, File.basename(sheet)) %>" rel="stylesheet" />
<%- end -%>

View file

@ -1,31 +0,0 @@
<ul class="nav nav-sidebar">
<%- navigation.each.with_index do |topic_group, groupidx| -%>
<%- current_group = topic_group[:id] == group_id -%>
<li class="nav-header">
<a class="" href="#" data-toggle="collapse" data-target="#topicGroup<%= groupidx %>">
<span id="tgSpan<%= groupidx %>" class="fa <%= current_group ? 'fa-angle-down' : 'fa-angle-right' %>"></span><%= topic_group[:name] %>
</a>
<ul id="topicGroup<%= groupidx %>" class="collapse <%= current_group ? 'in' : '' %> list-unstyled">
<%- topic_group[:topics].each.with_index do |topic, topicidx| -%>
<%- if not topic.has_key?(:topics) -%>
<%- current_topic = current_group && (topic[:id] == topic_id) -%>
<li><a class="<%= current_topic ? ' active' : '' %>" href="<%= subtopic_shim %><%= topic[:path] %>"><%= topic[:name] %></a></li>
<%- else -%>
<%- current_subgroup = topic[:id] == subgroup_id -%>
<li class="nav-header">
<a class="" href="#" data-toggle="collapse" data-target="#topicSubGroup-<%= groupidx %>-<%= topicidx %>">
<span id="sgSpan-<%= groupidx %>-<%= topicidx %>" class="fa <%= current_subgroup ? 'fa-caret-down' : 'fa-caret-right' %>"></span>&nbsp;<%= topic[:name] %>
</a>
<ul id="topicSubGroup-<%= groupidx %>-<%= topicidx %>" class="nav-tertiary list-unstyled collapse<%= current_subgroup ? ' in' : '' %>">
<%- topic[:topics].each do |subtopic| -%>
<%- current_subtopic = current_group && current_subgroup && (subtopic[:id] == topic_id) %>
<li><a class="<%= current_subtopic ? ' active' : '' %>" href="<%= subtopic_shim %><%= subtopic[:path] %>"><%= subtopic[:name] %></a></li>
<%- end -%>
</ul>
</li>
<%- end -%>
<%- end -%>
</ul>
</li>
<%- end -%>
</ul>

View file

@ -1,187 +0,0 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta content="IE=edge" http-equiv="X-UA-Compatible">
<meta content="width=device-width, initial-scale=1.0" name="viewport">
<title><%= distro %> <%= version %> | <%= [group_title, subgroup_title, topic_title].compact.join(' | ') %></title>
<!-- Bootstrap -->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css">
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap-theme.min.css">
<!-- Overpass Font -->
<link rel="stylesheet" href="https://overpass-30e2.kxcdn.com/overpass.css">
<%= render("_templates/_css.html.erb", :css_path => css_path) %>
<!-- HTML5 shim and Respond.js for IE8 support of HTML5 elements and media queries -->
<!-- WARNING: Respond.js doesn't work if you view the page via file:// -->
<!--[if lt IE 9]>
<script src="https://oss.maxcdn.com/html5shiv/3.7.2/html5shiv.min.js"></script>
<script src="https://oss.maxcdn.com/respond/1.4.2/respond.min.js"></script>
<![endif]-->
<link href="<%= File.join(images_path, "favicon32x32.png") %>" rel="shortcut icon" type="text/css">
<!--[if IE]><link rel="shortcut icon" href="<%= File.join(images_path, "favicon.ico") %>"><![endif]-->
<meta content="AsciiBinder" name="application-name">
</head>
<body>
<%- if version == "Rawhide" %>
<div class="corner-ribbon"><a href="https://pagure.io/fedora-docs/<%= repo_path.sub('/') {|s| "/blob/#{branch}/f/en-US/"} %>">Improve this Page</a></div>
<%- end %>
<div class="navbar navbar-default" role="navigation">
<div class="container-fluid">
<div class="navbar-header">
<a class="navbar-brand" href="https://docs.fedoraproject.org/"><img alt="Fedora Documentation" src="<%= File.join(images_path, "fedora.svg") %>"></a>
</div>
</div>
</div>
<div class="container">
<p class="toggle-nav visible-xs pull-left">
<button class="btn btn-default btn-sm" type="button" data-toggle="offcanvas">Toggle nav</button>
</p>
<ol class="breadcrumb">
<li class="sitename">
<a href="<%= site_home_path %>"><%= site_name %></a>
</li>
<li class="hidden-xs active">
<%= breadcrumb_root %>
</li>
<li class="hidden-xs active">
<%= breadcrumb_group %>
</li>
<%= breadcrumb_subgroup_block %>
<li class="hidden-xs active">
<%= breadcrumb_topic %>
</li>
</ol>
<div class="row row-offcanvas row-offcanvas-left">
<div class="col-xs-8 col-sm-3 col-md-3 sidebar sidebar-offcanvas">
<%= render("_templates/_nav.html.erb", :navigation => navigation, :group_id => group_id, :topic_id => topic_id, :subgroup_id => subgroup_id, :subtopic_shim => subtopic_shim) %>
</div>
<div class="col-xs-12 col-sm-9 col-md-9 main">
<div class="page-header">
<h2><%= article_title %></h2>
</div>
<%= content %>
</div>
</div>
</div>
<div id="bottom" class="text-muted py-3" >
<div class="foot">
<div class="container">
<div class="row footerlinks">
<div class="col-sm-3 col-xs-6 widget">
<h3 class="widget-title">About</h3>
<div class="widget-body">
<dl>
<dd><a href="https://fedoraproject.org/wiki/Overview">About Fedora</a></dd>
<dd><a href="https://getfedora.org/en/sponsors">Sponsors</a></dd>
<dd><a href="https://fedoramagazine.org">Fedora Magazine</a></dd>
<dd><a href="https://fedoraproject.org/wiki/Legal:Main#Legal">Legal</a></dd>
</dl>
<ul class="list-inline">
<li>
<a href="https://www.facebook.com/TheFedoraProject" class="btn-social btn-outline"><i class="fa fa-fw fa-facebook"></i></a>
</li>
<li>
<a href="https://plus.google.com/112917221531140868607" class="btn-social btn-outline"><i class="fa fa-fw fa-google-plus"></i></a>
</li>
<li>
<a href="https://twitter.com/fedora" class="btn-social btn-outline"><i class="fa fa-fw fa-twitter"></i></a>
</li>
</ul>
</div>
</div>
<div class="col-sm-3 col-xs-6 widget">
<h3 class="widget-title uppercase">Download</h3>
<div class="widget-body">
<dl>
<dd><a href="https://getfedora.org/en/workstation/download">Get Fedora Workstation</a></dd>
<dd><a href="https://getfedora.org/en/server/download">Get Fedora Server</a></dd>
<dd><a href="https://getfedora.org/en/atomic/download">Get Fedora Atomic</a></dd>
<dd><a href="https://spins.fedoraproject.org">Fedora Spins</a></dd>
<dd><a href="https://labs.fedoraproject.org">Fedora Labs</a></dd>
<dd><a href="https://arm.fedoraproject.org">Fedora ARM<span class="sup">&reg;</span></a></dd>
<dd><a href="https://alt.fedoraproject.org/">Alternative Downloads</a></dd>
</dl>
</div>
</div>
<div class="col-sm-3 col-xs-6 widget">
<h3 class="widget-title">Support</h3>
<div class="widget-body">
<dl>
<dd><a href="https://fedoraproject.org/wiki/Communicating_and_getting_help">Get Help</a></dd>
<dd><a href="https://ask.fedoraproject.org/">Ask Fedora</a></dd>
<dd><a href="https://fedoraproject.org/wiki/Common_F27_bugs">Common Bugs</a></dd>
<dd><a href="https://developer.fedoraproject.org/">Fedora Developer Portal</a></dd>
<dd><a href="https://docs.fedoraproject.org/f27/install-guide/index.html">Installation Guide</a></dd>
</dl>
</div>
</div>
<div class="col-sm-3 col-xs-6 widget">
<h3 class="widget-title">Join</h3>
<div class="widget-body">
<dl>
<dd><a href="https://fedoraproject.org/wiki/Join">Join Fedora</a></dd>
<dd><a href="http://fedoraplanet.org">Planet Fedora</a></dd>
<dd><a href="https://fedoraproject.org/wiki/SIGs">Fedora SIGs</a></dd>
<dd><a href="https://admin.fedoraproject.org/accounts/">Fedora Account System</a></dd>
<dd><a href="https://fedoracommunity.org/">Fedora Community</a></dd>
</dl>
</div>
</div>
</div> <!-- /row of widgets -->
<div class="row">
<div class="col-md-2">
<div class="widget-body">
<a href="https://www.redhat.com/"><img class="rh-logo" src="<%= File.join(images_path, "redhat-logo.png") %>" alt="Red Hat Logo" /></a>
</div>
</div>
<div class="col-md-7">
<div class="widget-body">
<p class="sponsor">Fedora is sponsored by Red Hat.</p>
<p class="sponsor"><a href="https://www.redhat.com/en/technologies/linux-platforms/articles/relationship-between-fedora-and-rhel">Learn more about the relationship between Red Hat and Fedora &raquo;</a></p>
<p class="copy">&copy; 2017 Red Hat, Inc. and others. Please send any comments or corrections to the <a href="https://pagure.io/fedora-docs/docs-fp-o">documentation team</a></p>
</div>
</div>
</div> <!-- /row of widgets -->
</div>
</div>
</div>
<!-- jQuery (necessary for Bootstrap's JavaScript plugins) -->
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>
<!-- Latest compiled and minified JavaScript -->
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/js/bootstrap.min.js"></script>
<script src="<%= File.join(javascripts_path, "bootstrap-offcanvas.js") %>" type="text/javascript"></script>
<script type="text/javascript">
/*<![CDATA[*/
$(document).ready(function() {
$("[id^='topicGroup']").on('show.bs.collapse', function (event) {
if (!($(event.target).attr('id').match(/^topicSubGroup/))) {
$(this).parent().find("[id^='tgSpan']").toggleClass("fa-angle-right fa-angle-down");
}
});
$("[id^='topicGroup']").on('hide.bs.collapse', function (event) {
if (!($(event.target).attr('id').match(/^topicSubGroup/))) {
$(this).parent().find("[id^='tgSpan']").toggleClass("fa-angle-right fa-angle-down");
}
});
$("[id^='topicSubGroup']").on('show.bs.collapse', function () {
$(this).parent().find("[id^='sgSpan']").toggleClass("fa-caret-right fa-caret-down");
});
$("[id^='topicSubGroup']").on('hide.bs.collapse', function () {
$(this).parent().find("[id^='sgSpan']").toggleClass("fa-caret-right fa-caret-down");
});
});
/*]]>*/
</script>
</body>
</html>

View file

@ -1,75 +0,0 @@
# This configuration file dictates the organization of the topic groups and
# topics on the main page of the doc site for this branch. Each record
# consists of the following:
#
# --- <= Record delimiter
# Name: Origin of the Species <= Display name of topic group
# Dir: origin_of_the_species <= Directory name of topic group
# Topics:
# - Name: The Majestic Marmoset <= Topic name
# File: the_majestic_marmoset <= Topic file under group dir +/-
# - Name: The Curious Crocodile <= Topic 2 name
# File: the_curious_crocodile <= Topic 2 file
# - Name: The Numerous Nematodes <= Sub-topic group name
# Dir: the_numerous_nematodes <= Sub-topic group dir
# Topics:
# - Name: The Wily Worm <= Sub-topic name
# File: the_wily_worm <= Sub-topic file under <group dir>/<subtopic dir>
# - Name: The Acrobatic Ascarid <= Sub-topic 2 name
# File: the_acrobatic_ascarid <= Sub-topic 2 file under <group dir>/<subtopic dir>
#
# The ordering of the records in this document determines the ordering of the
# topic groups and topics on the main page.
---
Name: Defensive Coding Guide
Dir: en-US
Topics:
- Name: Book Information
File: index
- Name: Programming Languages
Dir: programming-languages
Topics:
- Name: The C Programming Language
File: C
- Name: The C++ Programming&nbsp;Language
File: CXX
- Name: The Java Programming Language
File: Java
- Name: The Python Programming Language
File: Python
- Name: Shell Programming and bash
File: Shell
- Name: The Go Programming Language
File: Go
- Name: The Vala Programming Language
File: Vala
- Name: Specific Programming Tasks
Dir: tasks
Topics:
- Name: Library Design
File: Tasks-Library_Design
- Name: File Descriptor Management
File: Tasks-Descriptors
- Name: File System Manipulation
File: Tasks-File_System
- Name: Temporary Files
File: Tasks-Temporary_Files
- Name: Processes
File: Tasks-Processes
- Name: Serialization and Deserialization
File: Tasks-Serialization
- Name: Cryptography
File: Tasks-Cryptography
- Name: RPM Packaging
File: Tasks-Packaging
- Name: Implementing Security Features
Dir: features
Topics:
- Name: Authentication and Authorization
File: Features-Authentication
- Name: Transport Layer Security (TLS)
File: Features-TLS
- Name: Hardware Security Modules and Smart Cards
File: Features-HSM
- Name: Revision History
File: Revision_History

16
antora.yml Normal file
View file

@ -0,0 +1,16 @@
# Name will be mostly visible in the URL. Treat it as an indentifier.
# Tip: If you want to use the local preview scripts that come with this repository, please change this value in the site.yml file as well. (under site/start_page)
name: defensive-coding
# Title will be visible on the page.
title: Defensive Coding Guide
# If you don't plan to have multiple versions of the docs (for example, to document multiple versions of some software), you can ignore this field. Otherwise, change "master" to a specific version.
version: master
# We encourage you to name the index page as "index.adoc". If you absolutely have to use a different name, please reflect it here. You can ignore this field otherwise.
start_page: ROOT:index
# This lists all the menu definitions of your component.
nav:
- modules/ROOT/nav.adoc

16
build.sh Executable file
View file

@ -0,0 +1,16 @@
#!/bin/sh
if [ "$(uname)" == "Darwin" ]; then
# Running on macOS.
# Let's assume that the user has the Docker CE installed
# which doesn't require a root password.
docker run --rm -it -v $(pwd):/antora antora/antora --html-url-extension-style=indexify site.yml
elif [ "$(expr substr $(uname -s) 1 5)" == "Linux" ]; then
# Running on Linux.
# Let's assume that it's running the Docker deamon
# which requires root.
echo ""
echo "This build script is using Docker to run the build in an isolated environment. You might be asked for a root password in order to start it."
sudo docker run --rm -it -v $(pwd):/antora:z antora/antora --html-url-extension-style=indexify site.yml
fi

View file

@ -1,141 +0,0 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<!-- The above 3 meta tags *must* come first in the head; any other head content must come *after* these tags -->
<title>Fedora Defensive Coding Guide Docs Website</title>
<!-- Bootstrap -->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css">
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap-theme.min.css">
<link rel="stylesheet" href="https://overpass-30e2.kxcdn.com/overpass.css">
<link rel="stylesheet" href="_stylesheets/asciibinder.css">
<!-- HTML5 shim and Respond.js for IE8 support of HTML5 elements and media queries -->
<!-- WARNING: Respond.js doesn't work if you view the page via file:// -->
<!--[if lt IE 9]>
<script src="https://oss.maxcdn.com/html5shiv/3.7.2/html5shiv.min.js"></script>
<script src="https://oss.maxcdn.com/respond/1.4.2/respond.min.js"></script>
<![endif]-->
</head>
<body>
<div class="container">
<div class="row">
<div class="page-header">
<img src="_images/fedora.svg" class="img-responsive" />
</div>
</div>
<div class="row">
<div class="col-md-8">
<h4><strong>Fedora Defensive Coding Guide Docs Site</strong></h4>
<p>Test Build.</p>
</div>
<div class="col-md-4">
<h5><strong>Fedora Defensive Coding Guide Docs</strong></h5>
<div class="list-group">
<a href="master/en-US/index.html" class="list-group-item">
&nbsp;Documentation
</a>
</div>
</div>
</div>
</div>
<div id="bottom" class="text-muted py-3" >
<div class="foot">
<div class="container">
<div class="row footerlinks">
<div class="col-sm-3 col-xs-6 widget">
<h3 class="widget-title">About</h3>
<div class="widget-body">
<dl>
<dd><a href="https://fedoraproject.org/wiki/Overview">About Fedora</a></dd>
<dd><a href="https://getfedora.org/en/sponsors">Sponsors</a></dd>
<dd><a href="https://fedoramagazine.org">Fedora Magazine</a></dd>
<dd><a href="https:https://fedoraproject.org/wiki/Legal:Main#Legal">Legal</a></dd>
</dl>
<ul class="list-inline">
<li>
<a href="https:https://www.facebook.com/TheFedoraProject" class="btn-social btn-outline"><i class="fa fa-fw fa-facebook"></i></a>
</li>
<li>
<a href="https:https://plus.google.com/112917221531140868607" class="btn-social btn-outline"><i class="fa fa-fw fa-google-plus"></i></a>
</li>
<li>
<a href="https:https://twitter.com/fedora" class="btn-social btn-outline"><i class="fa fa-fw fa-twitter"></i></a>
</li>
</ul>
</div>
</div>
<div class="col-sm-3 col-xs-6 widget">
<h3 class="widget-title uppercase">Download</h3>
<div class="widget-body">
<dl>
<dd><a href="https://getfedora.org/en/workstation/download">Get Fedora Workstation</a></dd>
<dd><a href="https://getfedora.org/en/server/download">Get Fedora Server</a></dd>
<dd><a href="https://getfedora.org/en/atomic/download">Get Fedora Atomic</a></dd>
<dd><a href="https://spins.fedoraproject.org">Fedora Spins</a></dd>
<dd><a href="https://labs.fedoraproject.org">Fedora Labs</a></dd>
<dd><a href="https://arm.fedoraproject.org">Fedora ARM<span class="sup">&reg;</span></a></dd>
<dd><a href="https://alt.fedoraproject.org/">Alternative Downloads</a></dd>
</dl>
</div>
</div>
<div class="col-sm-3 col-xs-6 widget">
<h3 class="widget-title">Support</h3>
<div class="widget-body">
<dl>
<dd><a href="https://fedoraproject.org/wiki/Communicating_and_getting_help">Get Help</a></dd>
<dd><a href="https://ask.fedoraproject.org/">Ask Fedora</a></dd>
<dd><a href="https://fedoraproject.org/wiki/Common_F${global_variables.release['curr_id']}_bugs">Common Bugs</a></dd>
<dd><a href="https://developer.fedoraproject.org/">Fedora Developer Portal</a></dd>
<dd><a href="https://docs.fedoraproject.org/en-US/Fedora/${global_variables.release['curr_id']}/html/Installation_Guide">Installation Guide</a></dd>
</dl>
</div>
</div>
<div class="col-sm-3 col-xs-6 widget">
<h3 class="widget-title">Join</h3>
<div class="widget-body">
<dl>
<dd><a href="https://fedoraproject.org/wiki/Join">Join Fedora</a></dd>
<dd><a href="http://fedoraplanet.org">Planet Fedora</a></dd>
<dd><a href="https://fedoraproject.org/wiki/SIGs">Fedora SIGs</a></dd>
<dd><a href="https://admin.fedoraproject.org/accounts/">Fedora Account System</a></dd>
<dd><a href="https://fedoracommunity.org/">Fedora Community</a></dd>
</dl>
</div>
</div>
</div> <!-- /row of widgets -->
<div class="row">
<div class="col-md-2">
<div class="widget-body">
<a href="https://www.redhat.com/"><img class="rh-logo" src="_images/redhat-logo.png" alt="Red Hat Logo" /></a>
</div>
</div>
<div class="col-md-7">
<div class="widget-body">
<p class="sponsor">Fedora is sponsored by Red Hat.</p>
<p class="sponsor"><a href="https://www.redhat.com/en/technologies/linux-platforms/articles/relationship-between-fedora-and-rhel">Learn more about the relationship between Red Hat and Fedora &raquo;</a></p>
<p class="copy">&copy; 2017 Red Hat, Inc. and others. Please send any comments or corrections to the <a href="https://fedorahosted.org/fedora-websites/">websites team</a></p>
</div>
</div>
</div> <!-- /row of widgets -->
</div>
</div>
</div>
<!-- jQuery (necessary for Bootstrap's JavaScript plugins) -->
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>
<!-- Include all compiled plugins (below), or include individual files as needed -->
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/js/bootstrap.min.js"></script>
</body>
</html>

View file

Before

Width:  |  Height:  |  Size: 7.6 KiB

After

Width:  |  Height:  |  Size: 7.6 KiB

Before After
Before After

23
modules/ROOT/nav.adoc Normal file
View file

@ -0,0 +1,23 @@
* xref:index.adoc[Book Information]
* Programming Languages
** xref:programming-languages/C.adoc[The C Programming Language]
** xref:programming-languages/CXX.adoc[The C++ Programming&nbsp;Language]
** xref:programming-languages/Java.adoc[The Java Programming Language]
** xref:programming-languages/Python.adoc[The Python Programming Language]
** xref:programming-languages/Shell.adoc[Shell Programming and bash]
** xref:programming-languages/Go.adoc[The Go Programming Language]
** xref:programming-languages/Vala.adoc[The Vala Programming Language]
* Specific Programming Tasks
** xref:tasks/Tasks-Library_Design.adoc[Library Design]
** xref:tasks/Tasks-Descriptors.adoc[File Descriptor Management]
** xref:tasks/Tasks-File_System.adoc[File System Manipulation]
** xref:tasks/Tasks-Temporary_Files.adoc[Temporary Files]
** xref:tasks/Tasks-Processes.adoc[Processes]
** xref:tasks/Tasks-Serialization.adoc[Serialization and Deserialization]
** xref:tasks/Tasks-Cryptography.adoc[Cryptography]
** xref:tasks/Tasks-Packaging.adoc[RPM Packaging]
* Implementing Security Features
** xref:features/Features-Authentication.adoc[Authentication and Authorization]
** xref:features/Features-TLS.adoc[Transport Layer Security (TLS)]
** xref:features/Features-HSM.adoc[Hardware Security Modules and Smart Cards]
* xref:Revision_History.adoc[Revision History]

Some files were not shown because too many files have changed in this diff Show more