Converted to AsciiBinder
This required moving files around in the repository and shifting from a master.adoc structure to _topic_map.yml, etc. README and Makefile modified slightly to reflect new build process
17
Makefile
|
@ -1,29 +1,16 @@
|
|||
all: build
|
||||
all: build-snippets
|
||||
|
||||
include src/src.mk
|
||||
|
||||
.PHONY: all build build-manual build-snippets build-manual-html build-manual-epub force clean
|
||||
.PHONY: all build force clean
|
||||
|
||||
#build: build-src build-manual
|
||||
build: build-manual
|
||||
|
||||
build-snippets:
|
||||
mkdir -p en-US/snippets
|
||||
python scripts/split-snippets.py . \
|
||||
src/*.c src/*.cpp src/*.java src/*.py src/*.go src/*.sh
|
||||
|
||||
build-manual: build-snippets
|
||||
rm -rf html && mkdir html
|
||||
cd en-US && asciidoctor -n master.adoc -D ../html && cp -ar Common_Content/ ../html/
|
||||
|
||||
build-manual-html: build-manual
|
||||
|
||||
build-manual-epub: build-snippets
|
||||
false
|
||||
|
||||
build-manual-pdf: build-snippets
|
||||
false
|
||||
|
||||
clean: clean-src
|
||||
-rm -rf html
|
||||
-rm -rf en-US/*/snippets
|
||||
|
|
18
README.md
|
@ -1,6 +1,6 @@
|
|||
# Security coding guide
|
||||
|
||||
This is a fork of the Fedora secure coding guide.
|
||||
This is Fedora secure coding guide.
|
||||
|
||||
The guide is present in HTML form (auto-generated from this
|
||||
repository) at:
|
||||
|
@ -10,17 +10,17 @@ repository) at:
|
|||
|
||||
# Building HTML documentation
|
||||
|
||||
Just type "make". If you do not want to build the example code, run
|
||||
"make build-manual".
|
||||
1. Type "make".
|
||||
|
||||
When you type "make", the code examples in src/ are compiled (mainly
|
||||
to check for obvious syntax errors, but also for manual testing). If
|
||||
you lack the necessary libraries, you can type "make build-manual"
|
||||
instead, which will skip this step. The code examples are still
|
||||
included in the manual.
|
||||
When you type "make", the code examples in src/ are compiled (mainly
|
||||
to check for obvious syntax errors, but also for manual testing). If
|
||||
you lack the necessary libraries, the code examples are still
|
||||
included in the manual.
|
||||
|
||||
After this you need to run `asciibinder package` to produce the document.
|
||||
|
||||
|
||||
# Dependencies
|
||||
|
||||
Building the manual pages needs the "publican" and the "publican-fedora"
|
||||
packages.
|
||||
packages.
|
||||
|
|
11
_distro_map.yml
Normal file
|
@ -0,0 +1,11 @@
|
|||
---
|
||||
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
|
135
_images/404.html
Normal file
|
@ -0,0 +1,135 @@
|
|||
<!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">®</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 »</a></p>
|
||||
<p class="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>
|
BIN
_images/favicon.ico
Normal file
After Width: | Height: | Size: 5.3 KiB |
BIN
_images/favicon32x32.png
Normal file
After Width: | Height: | Size: 1.5 KiB |
Before Width: | Height: | Size: 7.6 KiB After Width: | Height: | Size: 7.6 KiB |
BIN
_images/redhat-logo.png
Normal file
After Width: | Height: | Size: 3.9 KiB |
0
_javascripts/.gitkeep
Normal file
6
_javascripts/bootstrap-offcanvas.js
vendored
Normal file
|
@ -0,0 +1,6 @@
|
|||
$(document).ready(function () {
|
||||
$('[data-toggle="offcanvas"]').click(function () {
|
||||
$('.sidebar').show();
|
||||
$('.row-offcanvas').toggleClass('active');
|
||||
});
|
||||
});
|
135
_package/main/_images/404.html
Normal file
|
@ -0,0 +1,135 @@
|
|||
<!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">®</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 »</a></p>
|
||||
<p class="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>
|
BIN
_package/main/_images/favicon.ico
Normal file
After Width: | Height: | Size: 5.3 KiB |
BIN
_package/main/_images/favicon32x32.png
Normal file
After Width: | Height: | Size: 1.5 KiB |
61
_package/main/_images/fedora.svg
Normal file
|
@ -0,0 +1,61 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
|
||||
<svg
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
version="1.0"
|
||||
width="220"
|
||||
height="70"
|
||||
id="svg6180">
|
||||
<defs
|
||||
id="defs6182" />
|
||||
<g
|
||||
transform="translate(-266.55899,-345.34488)"
|
||||
id="layer1">
|
||||
<path
|
||||
d="m 316.7736,397.581 c 0,0 0,0 -20.53889,0 0.3327,4.45245 3.92157,7.77609 8.70715,7.77609 3.38983,0 6.31456,-1.39616 8.64094,-3.65507 0.46553,-0.46679 0.99726,-0.59962 1.59519,-0.59962 0.79781,0 1.59561,0.39932 2.12692,1.06388 0.3327,0.46553 0.53216,0.99726 0.53216,1.52857 0,0.73118 -0.3327,1.52857 -0.93106,2.12734 -2.7919,2.99052 -7.51086,4.98503 -12.16403,4.98503 -8.44149,0 -15.22074,-6.77967 -15.22074,-15.22158 0,-8.44149 6.58022,-15.22074 15.02171,-15.22074 8.37529,0 14.62323,6.51317 14.62323,15.08749 0,1.26418 -1.12924,2.12861 -2.39258,2.12861 z m -12.23065,-11.76512 c -4.45329,0 -7.51085,2.92473 -8.17499,7.17731 10.03626,0 16.35083,0 16.35083,0 -0.59836,-4.05355 -3.78874,-7.17731 -8.17584,-7.17731 z"
|
||||
id="path11"
|
||||
style="fill:#3c6eb4" />
|
||||
<path
|
||||
d="m 375.46344,410.80807 c -8.44106,0 -15.22074,-6.77968 -15.22074,-15.22159 0,-8.44149 6.77968,-15.22074 15.22074,-15.22074 8.44234,0 15.22159,6.77925 15.22159,15.22074 -4.2e-4,8.44149 -6.77968,15.22159 -15.22159,15.22159 z m 0,-24.65992 c -5.31688,0 -8.77377,4.25427 -8.77377,9.43833 0,5.18364 3.45689,9.43833 8.77377,9.43833 5.31731,0 8.77504,-4.25469 8.77504,-9.43833 -4.2e-4,-5.18406 -3.45773,-9.43833 -8.77504,-9.43833 z"
|
||||
id="path13"
|
||||
style="fill:#3c6eb4" />
|
||||
<path
|
||||
d="m 412.66183,380.36574 c -4.45963,0 -7.40966,1.319 -10.01391,4.62956 l -0.24036,-1.53995 0,0 c -0.20198,-1.60743 -1.57326,-2.84926 -3.23382,-2.84926 -1.80139,0 -3.26206,1.459 -3.26206,3.26081 0,0.003 0,0.005 0,0.008 l 0,0 0,0.003 0,0 0,23.40712 c 0,1.79464 1.46194,3.25743 3.257,3.25743 1.79465,0 3.25744,-1.46279 3.25744,-3.25743 l 0,-12.56209 c 0,-5.71621 4.98502,-8.57432 10.23613,-8.57432 1.59519,0 2.85726,-1.32953 2.85726,-2.92515 0,-1.59561 -1.26207,-2.85726 -2.85768,-2.85726 z"
|
||||
id="path15"
|
||||
style="fill:#3c6eb4" />
|
||||
<path
|
||||
d="m 447.02614,395.58648 c 0.0666,-8.17541 -5.78326,-15.22074 -15.222,-15.22074 -8.44192,0 -15.28779,6.77925 -15.28779,15.22074 0,8.44191 6.64684,15.22159 14.68985,15.22159 4.01434,0 7.62682,-2.06621 9.23846,-4.22518 l 0.79359,2.01434 0,0 c 0.42589,1.13177 1.5176,1.93717 2.7978,1.93717 1.65001,0 2.98756,-1.33671 2.99009,-2.98545 l 0,0 0,-7.80687 0,0 0,-4.1556 z m -15.222,9.43833 c -5.31773,0 -8.77419,-4.25469 -8.77419,-9.43833 0,-5.18406 3.45604,-9.43833 8.77419,-9.43833 5.3173,0 8.77419,4.25427 8.77419,9.43833 0,5.18364 -3.45689,9.43833 -8.77419,9.43833 z"
|
||||
id="path17"
|
||||
style="fill:#3c6eb4" />
|
||||
<path
|
||||
d="m 355.01479,368.3337 c 0,-1.7938 -1.46194,-3.18997 -3.25659,-3.18997 -1.79422,0 -3.25743,1.39659 -3.25743,3.18997 l 0,17.1499 c -1.66097,-3.05756 -5.25026,-5.11786 -9.50495,-5.11786 -8.64052,0 -14.42336,6.51318 -14.42336,15.22074 0,8.70757 5.98229,15.22159 14.42336,15.22159 3.76555,0 7.03057,-1.55429 8.98587,-4.25554 l 0.72317,1.83428 c 0.44782,1.25912 1.64917,2.16024 3.06051,2.16024 1.78621,0 3.24984,-1.45435 3.24984,-3.24815 0,-0.005 0,-0.009 0,-0.0139 l 0,0 0,-38.95128 -4.2e-4,0 z m -15.22116,36.69111 c -5.31731,0 -8.70715,-4.25469 -8.70715,-9.43833 0,-5.18406 3.38984,-9.43833 8.70715,-9.43833 5.31773,0 8.70714,4.0544 8.70714,9.43833 0,5.38309 -3.38941,9.43833 -8.70714,9.43833 z"
|
||||
id="path19"
|
||||
style="fill:#3c6eb4" />
|
||||
<path
|
||||
d="m 287.21553,365.34023 c -0.59414,-0.0877 -1.19966,-0.13198 -1.80097,-0.13198 -6.73118,0 -12.20746,5.4767 -12.20746,12.20788 l 0,3.8132 -3.98903,0 c -1.46237,0 -2.65908,1.19671 -2.65908,2.65781 0,1.46321 1.19671,2.93738 2.65908,2.93738 l 3.98819,0 0,20.46004 c 0,1.79464 1.46236,3.25743 3.25658,3.25743 1.79507,0 3.25744,-1.46279 3.25744,-3.25743 l 0,-20.46004 4.40986,0 c 1.46194,0 2.65823,-1.47417 2.65823,-2.93738 0,-1.46152 -1.19629,-2.65823 -2.65823,-2.65823 l -4.40733,0 0,-3.8132 c 0,-3.13852 2.55323,-6.11469 5.69175,-6.11469 0.28294,0 0.56757,0.0211 0.84672,0.062 1.78031,0.26355 3.4358,-0.54269 3.70019,-2.32342 0.2627,-1.77904 -0.96606,-3.43538 -2.74594,-3.69935 z"
|
||||
id="path21"
|
||||
style="fill:#3c6eb4" />
|
||||
<path
|
||||
d="m 482.01243,363.57426 c 0,-10.06788 -8.16108,-18.22938 -18.22897,-18.22938 -10.06282,0 -18.22179,8.15475 -18.22854,18.21631 l -4.2e-4,-4.2e-4 0,14.1071 4.2e-4,4.2e-4 c 0.005,2.28463 1.85832,4.13409 4.14463,4.13409 0.007,0 0.0127,-8.4e-4 0.0194,-8.4e-4 l 0.001,8.4e-4 14.07083,0 0,0 c 10.06409,-0.004 18.22138,-8.16276 18.22138,-18.22812 z"
|
||||
id="path25"
|
||||
style="fill:#294172" />
|
||||
<path
|
||||
d="m 469.13577,349.66577 c -4.72528,0 -8.55576,3.83049 -8.55576,8.55577 0,0.002 0,0.004 0,0.006 l 0,4.52836 -4.51444,0 c -8.5e-4,0 -8.5e-4,0 -0.001,0 -4.72528,0 -8.55576,3.81193 -8.55576,8.53678 0,4.72528 3.83048,8.55577 8.55576,8.55577 4.72486,0 8.55534,-3.83049 8.55534,-8.55577 0,-0.002 0,-0.004 0,-0.006 l 0,-4.54733 4.51444,0 c 8.5e-4,0 0.001,0 0.002,0 4.72486,0 8.55534,-3.79296 8.55534,-8.51781 0,-4.72528 -3.83048,-8.55577 -8.55534,-8.55577 z m -8.55576,21.63483 c -0.004,2.48998 -2.02446,4.50811 -4.51571,4.50811 -2.49378,0 -4.53426,-2.02193 -4.53426,-4.5157 0,-2.49421 2.04048,-4.55366 4.53426,-4.55366 0.002,0 0.004,4.2e-4 0.006,4.2e-4 l 3.86971,0 c 0.001,0 0.002,-4.2e-4 0.003,-4.2e-4 0.35209,0 0.63799,0.28505 0.63799,0.63715 0,4.2e-4 -4.2e-4,8.4e-4 -4.2e-4,0.001 l 0,3.92284 -4.2e-4,0 z m 8.55534,-8.5448 c -0.001,0 -0.003,0 -0.004,0 l -3.87223,0 c -8.4e-4,0 -0.002,0 -0.002,0 -0.35252,0 -0.63757,-0.28506 -0.63757,-0.63758 l 0,-4.2e-4 0,-3.90343 c 0.004,-2.49083 2.02446,-4.50854 4.51571,-4.50854 2.49378,0 4.53468,2.02193 4.53468,4.51613 4.2e-4,2.49336 -2.04048,4.53384 -4.53426,4.53384 z"
|
||||
id="path29"
|
||||
style="fill:#3c6eb4" />
|
||||
<path
|
||||
d="m 460.58001,362.7558 0,-4.52836 c 0,-0.002 0,-0.004 0,-0.006 0,-4.72528 3.83048,-8.55577 8.55576,-8.55577 0.71685,0 1.22623,0.0805 1.88952,0.25469 0.96774,0.25385 1.75796,1.04618 1.75838,1.96922 4.2e-4,1.11575 -0.80919,1.92621 -2.0194,1.92621 -0.57642,0 -0.78473,-0.11048 -1.62892,-0.11048 -2.49125,0 -4.51149,2.01771 -4.51571,4.50854 l 0,3.90385 0,4.2e-4 c 0,0.35252 0.28505,0.63758 0.63757,0.63758 4.3e-4,0 0.001,0 0.002,0 l 2.96521,0 c 1.10521,0 1.99747,0.88467 1.99832,1.99283 0,1.10816 -0.89353,1.99114 -1.99832,1.99114 l -3.60489,0 0,4.54733 c 0,0.002 0,0.004 0,0.006 0,4.72485 -3.83048,8.55534 -8.55534,8.55534 -0.71684,0 -1.22623,-0.0805 -1.88952,-0.25469 -0.96774,-0.25343 -1.75838,-1.04618 -1.7588,-1.9688 0,-1.11575 0.80919,-1.92663 2.01982,-1.92663 0.576,0 0.78473,0.11048 1.6285,0.11048 2.49125,0 4.51191,-2.01771 4.51613,-4.50811 0,0 0,-3.92368 0,-3.9241 0,-0.35168 -0.2859,-0.63673 -0.63799,-0.63673 -4.3e-4,0 -8.5e-4,0 -0.002,0 l -2.96521,-4.2e-4 c -1.10521,0 -1.99831,-0.88214 -1.99831,-1.9903 -4.3e-4,-1.11533 0.90238,-1.99367 2.01939,-1.99367 l 3.58339,0 0,0 z"
|
||||
id="path31"
|
||||
style="fill:#ffffff" />
|
||||
<path
|
||||
d="m 477.41661,378.55292 2.81558,0 0,0.37898 -1.18152,0 0,2.94935 -0.45254,0 0,-2.94935 -1.18152,0 0,-0.37898 m 3.26144,0 0.67101,0 0.84937,2.26496 0.85381,-2.26496 0.67102,0 0,3.32833 -0.43917,0 0,-2.9226 -0.85828,2.28279 -0.45255,0 -0.85827,-2.28279 0,2.9226 -0.43694,0 0,-3.32833"
|
||||
id="text6223"
|
||||
style="fill:#294172;enable-background:new" />
|
||||
</g>
|
||||
<path
|
||||
d="m 181.98344,61.675273 2.81558,0 0,0.37898 -1.18152,0 0,2.94935 -0.45254,0 0,-2.94935 -1.18152,0 0,-0.37898 m 3.26144,0 0.67101,0 0.84937,2.26496 0.85381,-2.26496 0.67102,0 0,3.32833 -0.43917,0 0,-2.9226 -0.85828,2.28279 -0.45255,0 -0.85827,-2.28279 0,2.9226 -0.43694,0 0,-3.32833"
|
||||
id="path2391"
|
||||
style="fill:#294172;enable-background:new" />
|
||||
</svg>
|
After Width: | Height: | Size: 7.6 KiB |
BIN
_package/main/_images/redhat-logo.png
Normal file
After Width: | Height: | Size: 3.9 KiB |
598
_package/main/_stylesheets/asciibinder.css
Normal file
|
@ -0,0 +1,598 @@
|
|||
@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; }
|
141
_package/main/index.html
Normal file
|
@ -0,0 +1,141 @@
|
|||
<!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">
|
||||
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">®</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 »</a></p>
|
||||
<p class="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>
|
135
_package/main/master/_images/404.html
Normal file
|
@ -0,0 +1,135 @@
|
|||
<!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">®</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 »</a></p>
|
||||
<p class="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>
|
BIN
_package/main/master/_images/favicon.ico
Normal file
After Width: | Height: | Size: 5.3 KiB |
BIN
_package/main/master/_images/favicon32x32.png
Normal file
After Width: | Height: | Size: 1.5 KiB |
61
_package/main/master/_images/fedora.svg
Normal file
|
@ -0,0 +1,61 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
|
||||
<svg
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
version="1.0"
|
||||
width="220"
|
||||
height="70"
|
||||
id="svg6180">
|
||||
<defs
|
||||
id="defs6182" />
|
||||
<g
|
||||
transform="translate(-266.55899,-345.34488)"
|
||||
id="layer1">
|
||||
<path
|
||||
d="m 316.7736,397.581 c 0,0 0,0 -20.53889,0 0.3327,4.45245 3.92157,7.77609 8.70715,7.77609 3.38983,0 6.31456,-1.39616 8.64094,-3.65507 0.46553,-0.46679 0.99726,-0.59962 1.59519,-0.59962 0.79781,0 1.59561,0.39932 2.12692,1.06388 0.3327,0.46553 0.53216,0.99726 0.53216,1.52857 0,0.73118 -0.3327,1.52857 -0.93106,2.12734 -2.7919,2.99052 -7.51086,4.98503 -12.16403,4.98503 -8.44149,0 -15.22074,-6.77967 -15.22074,-15.22158 0,-8.44149 6.58022,-15.22074 15.02171,-15.22074 8.37529,0 14.62323,6.51317 14.62323,15.08749 0,1.26418 -1.12924,2.12861 -2.39258,2.12861 z m -12.23065,-11.76512 c -4.45329,0 -7.51085,2.92473 -8.17499,7.17731 10.03626,0 16.35083,0 16.35083,0 -0.59836,-4.05355 -3.78874,-7.17731 -8.17584,-7.17731 z"
|
||||
id="path11"
|
||||
style="fill:#3c6eb4" />
|
||||
<path
|
||||
d="m 375.46344,410.80807 c -8.44106,0 -15.22074,-6.77968 -15.22074,-15.22159 0,-8.44149 6.77968,-15.22074 15.22074,-15.22074 8.44234,0 15.22159,6.77925 15.22159,15.22074 -4.2e-4,8.44149 -6.77968,15.22159 -15.22159,15.22159 z m 0,-24.65992 c -5.31688,0 -8.77377,4.25427 -8.77377,9.43833 0,5.18364 3.45689,9.43833 8.77377,9.43833 5.31731,0 8.77504,-4.25469 8.77504,-9.43833 -4.2e-4,-5.18406 -3.45773,-9.43833 -8.77504,-9.43833 z"
|
||||
id="path13"
|
||||
style="fill:#3c6eb4" />
|
||||
<path
|
||||
d="m 412.66183,380.36574 c -4.45963,0 -7.40966,1.319 -10.01391,4.62956 l -0.24036,-1.53995 0,0 c -0.20198,-1.60743 -1.57326,-2.84926 -3.23382,-2.84926 -1.80139,0 -3.26206,1.459 -3.26206,3.26081 0,0.003 0,0.005 0,0.008 l 0,0 0,0.003 0,0 0,23.40712 c 0,1.79464 1.46194,3.25743 3.257,3.25743 1.79465,0 3.25744,-1.46279 3.25744,-3.25743 l 0,-12.56209 c 0,-5.71621 4.98502,-8.57432 10.23613,-8.57432 1.59519,0 2.85726,-1.32953 2.85726,-2.92515 0,-1.59561 -1.26207,-2.85726 -2.85768,-2.85726 z"
|
||||
id="path15"
|
||||
style="fill:#3c6eb4" />
|
||||
<path
|
||||
d="m 447.02614,395.58648 c 0.0666,-8.17541 -5.78326,-15.22074 -15.222,-15.22074 -8.44192,0 -15.28779,6.77925 -15.28779,15.22074 0,8.44191 6.64684,15.22159 14.68985,15.22159 4.01434,0 7.62682,-2.06621 9.23846,-4.22518 l 0.79359,2.01434 0,0 c 0.42589,1.13177 1.5176,1.93717 2.7978,1.93717 1.65001,0 2.98756,-1.33671 2.99009,-2.98545 l 0,0 0,-7.80687 0,0 0,-4.1556 z m -15.222,9.43833 c -5.31773,0 -8.77419,-4.25469 -8.77419,-9.43833 0,-5.18406 3.45604,-9.43833 8.77419,-9.43833 5.3173,0 8.77419,4.25427 8.77419,9.43833 0,5.18364 -3.45689,9.43833 -8.77419,9.43833 z"
|
||||
id="path17"
|
||||
style="fill:#3c6eb4" />
|
||||
<path
|
||||
d="m 355.01479,368.3337 c 0,-1.7938 -1.46194,-3.18997 -3.25659,-3.18997 -1.79422,0 -3.25743,1.39659 -3.25743,3.18997 l 0,17.1499 c -1.66097,-3.05756 -5.25026,-5.11786 -9.50495,-5.11786 -8.64052,0 -14.42336,6.51318 -14.42336,15.22074 0,8.70757 5.98229,15.22159 14.42336,15.22159 3.76555,0 7.03057,-1.55429 8.98587,-4.25554 l 0.72317,1.83428 c 0.44782,1.25912 1.64917,2.16024 3.06051,2.16024 1.78621,0 3.24984,-1.45435 3.24984,-3.24815 0,-0.005 0,-0.009 0,-0.0139 l 0,0 0,-38.95128 -4.2e-4,0 z m -15.22116,36.69111 c -5.31731,0 -8.70715,-4.25469 -8.70715,-9.43833 0,-5.18406 3.38984,-9.43833 8.70715,-9.43833 5.31773,0 8.70714,4.0544 8.70714,9.43833 0,5.38309 -3.38941,9.43833 -8.70714,9.43833 z"
|
||||
id="path19"
|
||||
style="fill:#3c6eb4" />
|
||||
<path
|
||||
d="m 287.21553,365.34023 c -0.59414,-0.0877 -1.19966,-0.13198 -1.80097,-0.13198 -6.73118,0 -12.20746,5.4767 -12.20746,12.20788 l 0,3.8132 -3.98903,0 c -1.46237,0 -2.65908,1.19671 -2.65908,2.65781 0,1.46321 1.19671,2.93738 2.65908,2.93738 l 3.98819,0 0,20.46004 c 0,1.79464 1.46236,3.25743 3.25658,3.25743 1.79507,0 3.25744,-1.46279 3.25744,-3.25743 l 0,-20.46004 4.40986,0 c 1.46194,0 2.65823,-1.47417 2.65823,-2.93738 0,-1.46152 -1.19629,-2.65823 -2.65823,-2.65823 l -4.40733,0 0,-3.8132 c 0,-3.13852 2.55323,-6.11469 5.69175,-6.11469 0.28294,0 0.56757,0.0211 0.84672,0.062 1.78031,0.26355 3.4358,-0.54269 3.70019,-2.32342 0.2627,-1.77904 -0.96606,-3.43538 -2.74594,-3.69935 z"
|
||||
id="path21"
|
||||
style="fill:#3c6eb4" />
|
||||
<path
|
||||
d="m 482.01243,363.57426 c 0,-10.06788 -8.16108,-18.22938 -18.22897,-18.22938 -10.06282,0 -18.22179,8.15475 -18.22854,18.21631 l -4.2e-4,-4.2e-4 0,14.1071 4.2e-4,4.2e-4 c 0.005,2.28463 1.85832,4.13409 4.14463,4.13409 0.007,0 0.0127,-8.4e-4 0.0194,-8.4e-4 l 0.001,8.4e-4 14.07083,0 0,0 c 10.06409,-0.004 18.22138,-8.16276 18.22138,-18.22812 z"
|
||||
id="path25"
|
||||
style="fill:#294172" />
|
||||
<path
|
||||
d="m 469.13577,349.66577 c -4.72528,0 -8.55576,3.83049 -8.55576,8.55577 0,0.002 0,0.004 0,0.006 l 0,4.52836 -4.51444,0 c -8.5e-4,0 -8.5e-4,0 -0.001,0 -4.72528,0 -8.55576,3.81193 -8.55576,8.53678 0,4.72528 3.83048,8.55577 8.55576,8.55577 4.72486,0 8.55534,-3.83049 8.55534,-8.55577 0,-0.002 0,-0.004 0,-0.006 l 0,-4.54733 4.51444,0 c 8.5e-4,0 0.001,0 0.002,0 4.72486,0 8.55534,-3.79296 8.55534,-8.51781 0,-4.72528 -3.83048,-8.55577 -8.55534,-8.55577 z m -8.55576,21.63483 c -0.004,2.48998 -2.02446,4.50811 -4.51571,4.50811 -2.49378,0 -4.53426,-2.02193 -4.53426,-4.5157 0,-2.49421 2.04048,-4.55366 4.53426,-4.55366 0.002,0 0.004,4.2e-4 0.006,4.2e-4 l 3.86971,0 c 0.001,0 0.002,-4.2e-4 0.003,-4.2e-4 0.35209,0 0.63799,0.28505 0.63799,0.63715 0,4.2e-4 -4.2e-4,8.4e-4 -4.2e-4,0.001 l 0,3.92284 -4.2e-4,0 z m 8.55534,-8.5448 c -0.001,0 -0.003,0 -0.004,0 l -3.87223,0 c -8.4e-4,0 -0.002,0 -0.002,0 -0.35252,0 -0.63757,-0.28506 -0.63757,-0.63758 l 0,-4.2e-4 0,-3.90343 c 0.004,-2.49083 2.02446,-4.50854 4.51571,-4.50854 2.49378,0 4.53468,2.02193 4.53468,4.51613 4.2e-4,2.49336 -2.04048,4.53384 -4.53426,4.53384 z"
|
||||
id="path29"
|
||||
style="fill:#3c6eb4" />
|
||||
<path
|
||||
d="m 460.58001,362.7558 0,-4.52836 c 0,-0.002 0,-0.004 0,-0.006 0,-4.72528 3.83048,-8.55577 8.55576,-8.55577 0.71685,0 1.22623,0.0805 1.88952,0.25469 0.96774,0.25385 1.75796,1.04618 1.75838,1.96922 4.2e-4,1.11575 -0.80919,1.92621 -2.0194,1.92621 -0.57642,0 -0.78473,-0.11048 -1.62892,-0.11048 -2.49125,0 -4.51149,2.01771 -4.51571,4.50854 l 0,3.90385 0,4.2e-4 c 0,0.35252 0.28505,0.63758 0.63757,0.63758 4.3e-4,0 0.001,0 0.002,0 l 2.96521,0 c 1.10521,0 1.99747,0.88467 1.99832,1.99283 0,1.10816 -0.89353,1.99114 -1.99832,1.99114 l -3.60489,0 0,4.54733 c 0,0.002 0,0.004 0,0.006 0,4.72485 -3.83048,8.55534 -8.55534,8.55534 -0.71684,0 -1.22623,-0.0805 -1.88952,-0.25469 -0.96774,-0.25343 -1.75838,-1.04618 -1.7588,-1.9688 0,-1.11575 0.80919,-1.92663 2.01982,-1.92663 0.576,0 0.78473,0.11048 1.6285,0.11048 2.49125,0 4.51191,-2.01771 4.51613,-4.50811 0,0 0,-3.92368 0,-3.9241 0,-0.35168 -0.2859,-0.63673 -0.63799,-0.63673 -4.3e-4,0 -8.5e-4,0 -0.002,0 l -2.96521,-4.2e-4 c -1.10521,0 -1.99831,-0.88214 -1.99831,-1.9903 -4.3e-4,-1.11533 0.90238,-1.99367 2.01939,-1.99367 l 3.58339,0 0,0 z"
|
||||
id="path31"
|
||||
style="fill:#ffffff" />
|
||||
<path
|
||||
d="m 477.41661,378.55292 2.81558,0 0,0.37898 -1.18152,0 0,2.94935 -0.45254,0 0,-2.94935 -1.18152,0 0,-0.37898 m 3.26144,0 0.67101,0 0.84937,2.26496 0.85381,-2.26496 0.67102,0 0,3.32833 -0.43917,0 0,-2.9226 -0.85828,2.28279 -0.45255,0 -0.85827,-2.28279 0,2.9226 -0.43694,0 0,-3.32833"
|
||||
id="text6223"
|
||||
style="fill:#294172;enable-background:new" />
|
||||
</g>
|
||||
<path
|
||||
d="m 181.98344,61.675273 2.81558,0 0,0.37898 -1.18152,0 0,2.94935 -0.45254,0 0,-2.94935 -1.18152,0 0,-0.37898 m 3.26144,0 0.67101,0 0.84937,2.26496 0.85381,-2.26496 0.67102,0 0,3.32833 -0.43917,0 0,-2.9226 -0.85828,2.28279 -0.45255,0 -0.85827,-2.28279 0,2.9226 -0.43694,0 0,-3.32833"
|
||||
id="path2391"
|
||||
style="fill:#294172;enable-background:new" />
|
||||
</svg>
|
After Width: | Height: | Size: 7.6 KiB |
BIN
_package/main/master/_images/redhat-logo.png
Normal file
After Width: | Height: | Size: 3.9 KiB |
6
_package/main/master/_javascripts/bootstrap-offcanvas.js
vendored
Normal file
|
@ -0,0 +1,6 @@
|
|||
$(document).ready(function () {
|
||||
$('[data-toggle="offcanvas"]').click(function () {
|
||||
$('.sidebar').show();
|
||||
$('.row-offcanvas').toggleClass('active');
|
||||
});
|
||||
});
|
598
_package/main/master/_stylesheets/asciibinder.css
Normal file
|
@ -0,0 +1,598 @@
|
|||
@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; }
|
348
_package/main/master/en-US/Revision_History.html
Normal file
|
@ -0,0 +1,348 @@
|
|||
<!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> 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 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> 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> 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’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">®</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 »</a></p>
|
||||
<p class="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>
|
410
_package/main/master/en-US/features/Features-Authentication.html
Normal file
|
@ -0,0 +1,410 @@
|
|||
<!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> 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 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> 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> 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’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">®</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 »</a></p>
|
||||
<p class="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>
|
617
_package/main/master/en-US/features/Features-HSM.html
Normal file
|
@ -0,0 +1,617 @@
|
|||
<!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> 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 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> 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> 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’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">"</span><span style="color:#D20">pkcs11</span><span style="color:#710">"</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">"</span><span style="color:#D20">loading: %s</span><span style="color:#b0b">\n</span><span style="color:#710">"</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">"</span><span style="color:#D20">MODULE_PATH</span><span style="color:#710">"</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 && !ENGINE_ctrl_cmd_string(e, <span style="background-color:hsla(0,100%,50%,0.05)"><span style="color:#710">"</span><span style="color:#D20">PIN</span><span style="color:#710">"</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">"</span><span style="color:#D20">cannot load: %s</span><span style="color:#b0b">\n</span><span style="color:#710">"</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">"</span><span style="color:#D20">sha256</span><span style="color:#710">"</span></span>);
|
||||
|
||||
EVP_MD_CTX_init(&ctx);
|
||||
<span style="color:#080;font-weight:bold">if</span> (EVP_DigestInit(&ctx, digest_algo) <= <span style="color:#00D">0</span>) {
|
||||
display_openssl_errors(__LINE__);
|
||||
exit(<span style="color:#00D">1</span>);
|
||||
}
|
||||
|
||||
EVP_SignInit(&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">"</span><span style="color:#D20">test data</span><span style="color:#710">"</span></span>
|
||||
<span style="color:#080;font-weight:bold">if</span> (EVP_SignUpdate(&ctx, TEST_DATA, <span style="color:#080;font-weight:bold">sizeof</span>(TEST_DATA) - <span style="color:#00D">1</span>) <= <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(&ctx, buf, &n, private_key) <= <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 < <span style="color:#00D">0</span>) {
|
||||
fprintf(stderr, <span style="background-color:hsla(0,100%,50%,0.05)"><span style="color:#710">"</span><span style="color:#D20">error in %d: %s</span><span style="color:#b0b">\n</span><span style="color:#710">"</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 < <span style="color:#00D">0</span>) {
|
||||
fprintf(stderr, <span style="background-color:hsla(0,100%,50%,0.05)"><span style="color:#710">"</span><span style="color:#D20">error in %d: %s</span><span style="color:#b0b">\n</span><span style="color:#710">"</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(&private_key);
|
||||
<span style="color:#080;font-weight:bold">if</span> (ret < <span style="color:#00D">0</span>) {
|
||||
fprintf(stderr, <span style="background-color:hsla(0,100%,50%,0.05)"><span style="color:#710">"</span><span style="color:#D20">error in %d: %s</span><span style="color:#b0b">\n</span><span style="color:#710">"</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 < <span style="color:#00D">0</span>) {
|
||||
fprintf(stderr, <span style="background-color:hsla(0,100%,50%,0.05)"><span style="color:#710">"</span><span style="color:#D20">error in %d: %s</span><span style="color:#b0b">\n</span><span style="color:#710">"</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>,
|
||||
&testdata, &signature);
|
||||
<span style="color:#080;font-weight:bold">if</span> (ret < <span style="color:#00D">0</span>) {
|
||||
fprintf(stderr, <span style="background-color:hsla(0,100%,50%,0.05)"><span style="color:#710">"</span><span style="color:#D20">error in %d: %s</span><span style="color:#b0b">\n</span><span style="color:#710">"</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 & GNUTLS_PIN_FINAL_TRY)
|
||||
printf(<span style="background-color:hsla(0,100%,50%,0.05)"><span style="color:#710">"</span><span style="color:#D20">This is the final try before locking!</span><span style="color:#b0b">\n</span><span style="color:#710">"</span></span>);
|
||||
<span style="color:#080;font-weight:bold">if</span> (flags & GNUTLS_PIN_COUNT_LOW)
|
||||
printf(<span style="background-color:hsla(0,100%,50%,0.05)"><span style="color:#710">"</span><span style="color:#D20">Only few tries left before locking!</span><span style="color:#b0b">\n</span><span style="color:#710">"</span></span>);
|
||||
<span style="color:#080;font-weight:bold">if</span> (flags & GNUTLS_PIN_WRONG)
|
||||
printf(<span style="background-color:hsla(0,100%,50%,0.05)"><span style="color:#710">"</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">"</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">"</span><span style="color:#D20">%s</span><span style="color:#710">"</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">"</span><span style="color:#D20">test data to sign</span><span style="color:#710">"</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 < <span style="color:#00D">3</span>) {
|
||||
fprintf(stderr, <span style="background-color:hsla(0,100%,50%,0.05)"><span style="color:#710">"</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">"</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">"</span><span style="color:#D20">.</span><span style="color:#710">"</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">"</span><span style="color:#D20">NSS initialization failed (err %d)</span><span style="color:#b0b">\n</span><span style="color:#710">"</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">"</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">"</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">"</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">"</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">"</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">"</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->keyType, SEC_OID_UNKNOWN);
|
||||
|
||||
fprintf(stderr, <span style="background-color:hsla(0,100%,50%,0.05)"><span style="color:#710">"</span><span style="color:#D20">Signing with alg = %s (%d)</span><span style="color:#b0b">\n</span><span style="color:#710">"</span></span>,
|
||||
SECOID_FindOIDTagDescription(algTag), algTag);
|
||||
|
||||
rv = SEC_SignData(&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">"</span><span style="color:#D20">sign with Private Key failed (err %d: %s)</span><span style="color:#b0b">\n</span><span style="color:#710">"</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 "My HSM" -libfile ${path_to_pkcs11_file} -dbdir .
|
||||
# Find the token name on your HSM
|
||||
$ modutil -list -dbdir .
|
||||
# find the cert on your token
|
||||
$ certutil -L -h ${token_name} -d .
|
||||
# pass the cert to your signing program
|
||||
$ NSS_Sign_Example "${token_name}:${cert_name}"</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) && 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">"</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">"</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">"</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">"</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">®</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 »</a></p>
|
||||
<p class="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>
|
1893
_package/main/master/en-US/features/Features-TLS.html
Normal file
304
_package/main/master/en-US/index.html
Normal file
1182
_package/main/master/en-US/programming-languages/C.html
Normal file
641
_package/main/master/en-US/programming-languages/CXX.html
Normal file
|
@ -0,0 +1,641 @@
|
|||
<!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 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 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> 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 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> 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> 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 > 0 && n >
|
||||
(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><tr1/*></code> header files. This includes
|
||||
<code>std::tr1::shared_ptr</code> (from
|
||||
<code><tr1/memory></code>) and
|
||||
<code>std::tr1::function</code> (from
|
||||
<code><tr1/functional></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<char></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’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">®</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 »</a></p>
|
||||
<p class="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>
|
356
_package/main/master/en-US/programming-languages/Go.html
Normal file
|
@ -0,0 +1,356 @@
|
|||
<!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> 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 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> 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> 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 <stdin> - 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 <stdin> - 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">®</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 »</a></p>
|
||||
<p class="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>
|
1109
_package/main/master/en-US/programming-languages/Java.html
Normal file
313
_package/main/master/en-US/programming-languages/Python.html
Normal file
|
@ -0,0 +1,313 @@
|
|||
<!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> 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 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> 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> 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">®</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 »</a></p>
|
||||
<p class="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>
|
699
_package/main/master/en-US/programming-languages/Shell.html
Normal file
|
@ -0,0 +1,699 @@
|
|||
<!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> 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 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> 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> 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>“…”</code>.</p>
|
||||
</div>
|
||||
<div class="listingblock">
|
||||
<div class="content">
|
||||
<pre class="CodeRay highlight"><code data-lang="bash">external-program "$arg1" "$arg2"</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="$(mktemp)"
|
||||
|
||||
cleanup () {
|
||||
rm -f -- "$tmpfile"
|
||||
}
|
||||
|
||||
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 <stdin> - 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 "$@" ; 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">®</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 »</a></p>
|
||||
<p class="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>
|
273
_package/main/master/en-US/programming-languages/Vala.html
Normal file
|
@ -0,0 +1,273 @@
|
|||
<!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> 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 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> 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> 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">®</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 »</a></p>
|
||||
<p class="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>
|
428
_package/main/master/en-US/tasks/Tasks-Cryptography.html
Normal file
|
@ -0,0 +1,428 @@
|
|||
<!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> 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 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> 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> 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">®</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 »</a></p>
|
||||
<p class="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>
|
497
_package/main/master/en-US/tasks/Tasks-Descriptors.html
Normal file
|
@ -0,0 +1,497 @@
|
|||
<!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> 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 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> 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> 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><stdio.h></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">®</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 »</a></p>
|
||||
<p class="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>
|
548
_package/main/master/en-US/tasks/Tasks-File_System.html
Normal file
|
@ -0,0 +1,548 @@
|
|||
<!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> 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 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> 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> 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("…​")</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">®</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 »</a></p>
|
||||
<p class="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>
|
425
_package/main/master/en-US/tasks/Tasks-Library_Design.html
Normal file
|
@ -0,0 +1,425 @@
|
|||
<!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> 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 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> 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> 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">®</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 »</a></p>
|
||||
<p class="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>
|
438
_package/main/master/en-US/tasks/Tasks-Packaging.html
Normal file
|
@ -0,0 +1,438 @@
|
|||
<!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> 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 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> 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> 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 "umask 077 && openssl genrsa -out %{tlskey} 2048 2>/dev/null" \
|
||||
%{tlsuser}
|
||||
fi
|
||||
if ! test -e %{tlscert} ; then
|
||||
cn="Automatically generated certificate for the %{tlsuser} service"
|
||||
req_args="-key %{tlskey} -out %{tlscert} -days 7305 -subj \"/CN=$cn/\""
|
||||
su -s /bin/bash \
|
||||
-c "openssl req -new -x509 -extensions usr_cert $req_args" \
|
||||
%{tlsuser}
|
||||
fi
|
||||
fi
|
||||
|
||||
%files
|
||||
%dir %attr(0755,%{tlsuser},%{tlsuser]) %{tlsdir}
|
||||
%ghost %attr(0600,%{tlsuser},%{tlsuser}) %config(noreplace) %{tlskey}
|
||||
%ghost %attr(0644,%{tlsuser},%{tlsuser}) %config(noreplace) %{tlscert}</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 && openssl genrsa -out %{tlskey} 2048 2>/dev/null)
|
||||
chown %{tlsuser} %{tlskey}
|
||||
fi
|
||||
if ! test -e %{tlscert} ; then
|
||||
cn="Automatically generated certificate for the %{tlsuser} service"
|
||||
openssl req -new -x509 -extensions usr_cert \
|
||||
-key %{tlskey} -out %{tlscert} -days 7305 -subj "/CN=$cn/"
|
||||
fi
|
||||
fi
|
||||
|
||||
%files
|
||||
%dir %attr(0755,root,root]) %{tlsdir}
|
||||
%ghost %attr(0600,%{tlsuser},%{tlsuser}) %config(noreplace) %{tlskey}
|
||||
%ghost %attr(0644,root,root) %config(noreplace) %{tlscert}</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">®</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 »</a></p>
|
||||
<p class="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>
|
702
_package/main/master/en-US/tasks/Tasks-Processes.html
Normal file
|
@ -0,0 +1,702 @@
|
|||
<!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> 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 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> 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> 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><defunct></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"><stdlib.h></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">®</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 »</a></p>
|
||||
<p class="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>
|
1031
_package/main/master/en-US/tasks/Tasks-Serialization.html
Normal file
472
_package/main/master/en-US/tasks/Tasks-Temporary_Files.html
Normal file
|
@ -0,0 +1,472 @@
|
|||
<!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> 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 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> 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> 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’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…​)</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">®</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 »</a></p>
|
||||
<p class="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>
|
1
_package/main/sitemap.xml
Normal file
135
_preview/fedora/master/_images/404.html
Normal file
|
@ -0,0 +1,135 @@
|
|||
<!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">®</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 »</a></p>
|
||||
<p class="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>
|
BIN
_preview/fedora/master/_images/favicon.ico
Normal file
After Width: | Height: | Size: 5.3 KiB |
BIN
_preview/fedora/master/_images/favicon32x32.png
Normal file
After Width: | Height: | Size: 1.5 KiB |
61
_preview/fedora/master/_images/fedora.svg
Normal file
|
@ -0,0 +1,61 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
|
||||
<svg
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
version="1.0"
|
||||
width="220"
|
||||
height="70"
|
||||
id="svg6180">
|
||||
<defs
|
||||
id="defs6182" />
|
||||
<g
|
||||
transform="translate(-266.55899,-345.34488)"
|
||||
id="layer1">
|
||||
<path
|
||||
d="m 316.7736,397.581 c 0,0 0,0 -20.53889,0 0.3327,4.45245 3.92157,7.77609 8.70715,7.77609 3.38983,0 6.31456,-1.39616 8.64094,-3.65507 0.46553,-0.46679 0.99726,-0.59962 1.59519,-0.59962 0.79781,0 1.59561,0.39932 2.12692,1.06388 0.3327,0.46553 0.53216,0.99726 0.53216,1.52857 0,0.73118 -0.3327,1.52857 -0.93106,2.12734 -2.7919,2.99052 -7.51086,4.98503 -12.16403,4.98503 -8.44149,0 -15.22074,-6.77967 -15.22074,-15.22158 0,-8.44149 6.58022,-15.22074 15.02171,-15.22074 8.37529,0 14.62323,6.51317 14.62323,15.08749 0,1.26418 -1.12924,2.12861 -2.39258,2.12861 z m -12.23065,-11.76512 c -4.45329,0 -7.51085,2.92473 -8.17499,7.17731 10.03626,0 16.35083,0 16.35083,0 -0.59836,-4.05355 -3.78874,-7.17731 -8.17584,-7.17731 z"
|
||||
id="path11"
|
||||
style="fill:#3c6eb4" />
|
||||
<path
|
||||
d="m 375.46344,410.80807 c -8.44106,0 -15.22074,-6.77968 -15.22074,-15.22159 0,-8.44149 6.77968,-15.22074 15.22074,-15.22074 8.44234,0 15.22159,6.77925 15.22159,15.22074 -4.2e-4,8.44149 -6.77968,15.22159 -15.22159,15.22159 z m 0,-24.65992 c -5.31688,0 -8.77377,4.25427 -8.77377,9.43833 0,5.18364 3.45689,9.43833 8.77377,9.43833 5.31731,0 8.77504,-4.25469 8.77504,-9.43833 -4.2e-4,-5.18406 -3.45773,-9.43833 -8.77504,-9.43833 z"
|
||||
id="path13"
|
||||
style="fill:#3c6eb4" />
|
||||
<path
|
||||
d="m 412.66183,380.36574 c -4.45963,0 -7.40966,1.319 -10.01391,4.62956 l -0.24036,-1.53995 0,0 c -0.20198,-1.60743 -1.57326,-2.84926 -3.23382,-2.84926 -1.80139,0 -3.26206,1.459 -3.26206,3.26081 0,0.003 0,0.005 0,0.008 l 0,0 0,0.003 0,0 0,23.40712 c 0,1.79464 1.46194,3.25743 3.257,3.25743 1.79465,0 3.25744,-1.46279 3.25744,-3.25743 l 0,-12.56209 c 0,-5.71621 4.98502,-8.57432 10.23613,-8.57432 1.59519,0 2.85726,-1.32953 2.85726,-2.92515 0,-1.59561 -1.26207,-2.85726 -2.85768,-2.85726 z"
|
||||
id="path15"
|
||||
style="fill:#3c6eb4" />
|
||||
<path
|
||||
d="m 447.02614,395.58648 c 0.0666,-8.17541 -5.78326,-15.22074 -15.222,-15.22074 -8.44192,0 -15.28779,6.77925 -15.28779,15.22074 0,8.44191 6.64684,15.22159 14.68985,15.22159 4.01434,0 7.62682,-2.06621 9.23846,-4.22518 l 0.79359,2.01434 0,0 c 0.42589,1.13177 1.5176,1.93717 2.7978,1.93717 1.65001,0 2.98756,-1.33671 2.99009,-2.98545 l 0,0 0,-7.80687 0,0 0,-4.1556 z m -15.222,9.43833 c -5.31773,0 -8.77419,-4.25469 -8.77419,-9.43833 0,-5.18406 3.45604,-9.43833 8.77419,-9.43833 5.3173,0 8.77419,4.25427 8.77419,9.43833 0,5.18364 -3.45689,9.43833 -8.77419,9.43833 z"
|
||||
id="path17"
|
||||
style="fill:#3c6eb4" />
|
||||
<path
|
||||
d="m 355.01479,368.3337 c 0,-1.7938 -1.46194,-3.18997 -3.25659,-3.18997 -1.79422,0 -3.25743,1.39659 -3.25743,3.18997 l 0,17.1499 c -1.66097,-3.05756 -5.25026,-5.11786 -9.50495,-5.11786 -8.64052,0 -14.42336,6.51318 -14.42336,15.22074 0,8.70757 5.98229,15.22159 14.42336,15.22159 3.76555,0 7.03057,-1.55429 8.98587,-4.25554 l 0.72317,1.83428 c 0.44782,1.25912 1.64917,2.16024 3.06051,2.16024 1.78621,0 3.24984,-1.45435 3.24984,-3.24815 0,-0.005 0,-0.009 0,-0.0139 l 0,0 0,-38.95128 -4.2e-4,0 z m -15.22116,36.69111 c -5.31731,0 -8.70715,-4.25469 -8.70715,-9.43833 0,-5.18406 3.38984,-9.43833 8.70715,-9.43833 5.31773,0 8.70714,4.0544 8.70714,9.43833 0,5.38309 -3.38941,9.43833 -8.70714,9.43833 z"
|
||||
id="path19"
|
||||
style="fill:#3c6eb4" />
|
||||
<path
|
||||
d="m 287.21553,365.34023 c -0.59414,-0.0877 -1.19966,-0.13198 -1.80097,-0.13198 -6.73118,0 -12.20746,5.4767 -12.20746,12.20788 l 0,3.8132 -3.98903,0 c -1.46237,0 -2.65908,1.19671 -2.65908,2.65781 0,1.46321 1.19671,2.93738 2.65908,2.93738 l 3.98819,0 0,20.46004 c 0,1.79464 1.46236,3.25743 3.25658,3.25743 1.79507,0 3.25744,-1.46279 3.25744,-3.25743 l 0,-20.46004 4.40986,0 c 1.46194,0 2.65823,-1.47417 2.65823,-2.93738 0,-1.46152 -1.19629,-2.65823 -2.65823,-2.65823 l -4.40733,0 0,-3.8132 c 0,-3.13852 2.55323,-6.11469 5.69175,-6.11469 0.28294,0 0.56757,0.0211 0.84672,0.062 1.78031,0.26355 3.4358,-0.54269 3.70019,-2.32342 0.2627,-1.77904 -0.96606,-3.43538 -2.74594,-3.69935 z"
|
||||
id="path21"
|
||||
style="fill:#3c6eb4" />
|
||||
<path
|
||||
d="m 482.01243,363.57426 c 0,-10.06788 -8.16108,-18.22938 -18.22897,-18.22938 -10.06282,0 -18.22179,8.15475 -18.22854,18.21631 l -4.2e-4,-4.2e-4 0,14.1071 4.2e-4,4.2e-4 c 0.005,2.28463 1.85832,4.13409 4.14463,4.13409 0.007,0 0.0127,-8.4e-4 0.0194,-8.4e-4 l 0.001,8.4e-4 14.07083,0 0,0 c 10.06409,-0.004 18.22138,-8.16276 18.22138,-18.22812 z"
|
||||
id="path25"
|
||||
style="fill:#294172" />
|
||||
<path
|
||||
d="m 469.13577,349.66577 c -4.72528,0 -8.55576,3.83049 -8.55576,8.55577 0,0.002 0,0.004 0,0.006 l 0,4.52836 -4.51444,0 c -8.5e-4,0 -8.5e-4,0 -0.001,0 -4.72528,0 -8.55576,3.81193 -8.55576,8.53678 0,4.72528 3.83048,8.55577 8.55576,8.55577 4.72486,0 8.55534,-3.83049 8.55534,-8.55577 0,-0.002 0,-0.004 0,-0.006 l 0,-4.54733 4.51444,0 c 8.5e-4,0 0.001,0 0.002,0 4.72486,0 8.55534,-3.79296 8.55534,-8.51781 0,-4.72528 -3.83048,-8.55577 -8.55534,-8.55577 z m -8.55576,21.63483 c -0.004,2.48998 -2.02446,4.50811 -4.51571,4.50811 -2.49378,0 -4.53426,-2.02193 -4.53426,-4.5157 0,-2.49421 2.04048,-4.55366 4.53426,-4.55366 0.002,0 0.004,4.2e-4 0.006,4.2e-4 l 3.86971,0 c 0.001,0 0.002,-4.2e-4 0.003,-4.2e-4 0.35209,0 0.63799,0.28505 0.63799,0.63715 0,4.2e-4 -4.2e-4,8.4e-4 -4.2e-4,0.001 l 0,3.92284 -4.2e-4,0 z m 8.55534,-8.5448 c -0.001,0 -0.003,0 -0.004,0 l -3.87223,0 c -8.4e-4,0 -0.002,0 -0.002,0 -0.35252,0 -0.63757,-0.28506 -0.63757,-0.63758 l 0,-4.2e-4 0,-3.90343 c 0.004,-2.49083 2.02446,-4.50854 4.51571,-4.50854 2.49378,0 4.53468,2.02193 4.53468,4.51613 4.2e-4,2.49336 -2.04048,4.53384 -4.53426,4.53384 z"
|
||||
id="path29"
|
||||
style="fill:#3c6eb4" />
|
||||
<path
|
||||
d="m 460.58001,362.7558 0,-4.52836 c 0,-0.002 0,-0.004 0,-0.006 0,-4.72528 3.83048,-8.55577 8.55576,-8.55577 0.71685,0 1.22623,0.0805 1.88952,0.25469 0.96774,0.25385 1.75796,1.04618 1.75838,1.96922 4.2e-4,1.11575 -0.80919,1.92621 -2.0194,1.92621 -0.57642,0 -0.78473,-0.11048 -1.62892,-0.11048 -2.49125,0 -4.51149,2.01771 -4.51571,4.50854 l 0,3.90385 0,4.2e-4 c 0,0.35252 0.28505,0.63758 0.63757,0.63758 4.3e-4,0 0.001,0 0.002,0 l 2.96521,0 c 1.10521,0 1.99747,0.88467 1.99832,1.99283 0,1.10816 -0.89353,1.99114 -1.99832,1.99114 l -3.60489,0 0,4.54733 c 0,0.002 0,0.004 0,0.006 0,4.72485 -3.83048,8.55534 -8.55534,8.55534 -0.71684,0 -1.22623,-0.0805 -1.88952,-0.25469 -0.96774,-0.25343 -1.75838,-1.04618 -1.7588,-1.9688 0,-1.11575 0.80919,-1.92663 2.01982,-1.92663 0.576,0 0.78473,0.11048 1.6285,0.11048 2.49125,0 4.51191,-2.01771 4.51613,-4.50811 0,0 0,-3.92368 0,-3.9241 0,-0.35168 -0.2859,-0.63673 -0.63799,-0.63673 -4.3e-4,0 -8.5e-4,0 -0.002,0 l -2.96521,-4.2e-4 c -1.10521,0 -1.99831,-0.88214 -1.99831,-1.9903 -4.3e-4,-1.11533 0.90238,-1.99367 2.01939,-1.99367 l 3.58339,0 0,0 z"
|
||||
id="path31"
|
||||
style="fill:#ffffff" />
|
||||
<path
|
||||
d="m 477.41661,378.55292 2.81558,0 0,0.37898 -1.18152,0 0,2.94935 -0.45254,0 0,-2.94935 -1.18152,0 0,-0.37898 m 3.26144,0 0.67101,0 0.84937,2.26496 0.85381,-2.26496 0.67102,0 0,3.32833 -0.43917,0 0,-2.9226 -0.85828,2.28279 -0.45255,0 -0.85827,-2.28279 0,2.9226 -0.43694,0 0,-3.32833"
|
||||
id="text6223"
|
||||
style="fill:#294172;enable-background:new" />
|
||||
</g>
|
||||
<path
|
||||
d="m 181.98344,61.675273 2.81558,0 0,0.37898 -1.18152,0 0,2.94935 -0.45254,0 0,-2.94935 -1.18152,0 0,-0.37898 m 3.26144,0 0.67101,0 0.84937,2.26496 0.85381,-2.26496 0.67102,0 0,3.32833 -0.43917,0 0,-2.9226 -0.85828,2.28279 -0.45255,0 -0.85827,-2.28279 0,2.9226 -0.43694,0 0,-3.32833"
|
||||
id="path2391"
|
||||
style="fill:#294172;enable-background:new" />
|
||||
</svg>
|
After Width: | Height: | Size: 7.6 KiB |
BIN
_preview/fedora/master/_images/redhat-logo.png
Normal file
After Width: | Height: | Size: 3.9 KiB |
6
_preview/fedora/master/_javascripts/bootstrap-offcanvas.js
vendored
Normal file
|
@ -0,0 +1,6 @@
|
|||
$(document).ready(function () {
|
||||
$('[data-toggle="offcanvas"]').click(function () {
|
||||
$('.sidebar').show();
|
||||
$('.row-offcanvas').toggleClass('active');
|
||||
});
|
||||
});
|
598
_preview/fedora/master/_stylesheets/asciibinder.css
Normal file
|
@ -0,0 +1,598 @@
|
|||
@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; }
|
348
_preview/fedora/master/en-US/Revision_History.html
Normal file
|
@ -0,0 +1,348 @@
|
|||
<!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> 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 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> 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> 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’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">®</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 »</a></p>
|
||||
<p class="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>
|
|
@ -0,0 +1,410 @@
|
|||
<!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> 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 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> 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> 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’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">®</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 »</a></p>
|
||||
<p class="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>
|
617
_preview/fedora/master/en-US/features/Features-HSM.html
Normal file
|
@ -0,0 +1,617 @@
|
|||
<!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> 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 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> 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> 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’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">"</span><span style="color:#D20">pkcs11</span><span style="color:#710">"</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">"</span><span style="color:#D20">loading: %s</span><span style="color:#b0b">\n</span><span style="color:#710">"</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">"</span><span style="color:#D20">MODULE_PATH</span><span style="color:#710">"</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 && !ENGINE_ctrl_cmd_string(e, <span style="background-color:hsla(0,100%,50%,0.05)"><span style="color:#710">"</span><span style="color:#D20">PIN</span><span style="color:#710">"</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">"</span><span style="color:#D20">cannot load: %s</span><span style="color:#b0b">\n</span><span style="color:#710">"</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">"</span><span style="color:#D20">sha256</span><span style="color:#710">"</span></span>);
|
||||
|
||||
EVP_MD_CTX_init(&ctx);
|
||||
<span style="color:#080;font-weight:bold">if</span> (EVP_DigestInit(&ctx, digest_algo) <= <span style="color:#00D">0</span>) {
|
||||
display_openssl_errors(__LINE__);
|
||||
exit(<span style="color:#00D">1</span>);
|
||||
}
|
||||
|
||||
EVP_SignInit(&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">"</span><span style="color:#D20">test data</span><span style="color:#710">"</span></span>
|
||||
<span style="color:#080;font-weight:bold">if</span> (EVP_SignUpdate(&ctx, TEST_DATA, <span style="color:#080;font-weight:bold">sizeof</span>(TEST_DATA) - <span style="color:#00D">1</span>) <= <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(&ctx, buf, &n, private_key) <= <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 < <span style="color:#00D">0</span>) {
|
||||
fprintf(stderr, <span style="background-color:hsla(0,100%,50%,0.05)"><span style="color:#710">"</span><span style="color:#D20">error in %d: %s</span><span style="color:#b0b">\n</span><span style="color:#710">"</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 < <span style="color:#00D">0</span>) {
|
||||
fprintf(stderr, <span style="background-color:hsla(0,100%,50%,0.05)"><span style="color:#710">"</span><span style="color:#D20">error in %d: %s</span><span style="color:#b0b">\n</span><span style="color:#710">"</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(&private_key);
|
||||
<span style="color:#080;font-weight:bold">if</span> (ret < <span style="color:#00D">0</span>) {
|
||||
fprintf(stderr, <span style="background-color:hsla(0,100%,50%,0.05)"><span style="color:#710">"</span><span style="color:#D20">error in %d: %s</span><span style="color:#b0b">\n</span><span style="color:#710">"</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 < <span style="color:#00D">0</span>) {
|
||||
fprintf(stderr, <span style="background-color:hsla(0,100%,50%,0.05)"><span style="color:#710">"</span><span style="color:#D20">error in %d: %s</span><span style="color:#b0b">\n</span><span style="color:#710">"</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>,
|
||||
&testdata, &signature);
|
||||
<span style="color:#080;font-weight:bold">if</span> (ret < <span style="color:#00D">0</span>) {
|
||||
fprintf(stderr, <span style="background-color:hsla(0,100%,50%,0.05)"><span style="color:#710">"</span><span style="color:#D20">error in %d: %s</span><span style="color:#b0b">\n</span><span style="color:#710">"</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 & GNUTLS_PIN_FINAL_TRY)
|
||||
printf(<span style="background-color:hsla(0,100%,50%,0.05)"><span style="color:#710">"</span><span style="color:#D20">This is the final try before locking!</span><span style="color:#b0b">\n</span><span style="color:#710">"</span></span>);
|
||||
<span style="color:#080;font-weight:bold">if</span> (flags & GNUTLS_PIN_COUNT_LOW)
|
||||
printf(<span style="background-color:hsla(0,100%,50%,0.05)"><span style="color:#710">"</span><span style="color:#D20">Only few tries left before locking!</span><span style="color:#b0b">\n</span><span style="color:#710">"</span></span>);
|
||||
<span style="color:#080;font-weight:bold">if</span> (flags & GNUTLS_PIN_WRONG)
|
||||
printf(<span style="background-color:hsla(0,100%,50%,0.05)"><span style="color:#710">"</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">"</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">"</span><span style="color:#D20">%s</span><span style="color:#710">"</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">"</span><span style="color:#D20">test data to sign</span><span style="color:#710">"</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 < <span style="color:#00D">3</span>) {
|
||||
fprintf(stderr, <span style="background-color:hsla(0,100%,50%,0.05)"><span style="color:#710">"</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">"</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">"</span><span style="color:#D20">.</span><span style="color:#710">"</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">"</span><span style="color:#D20">NSS initialization failed (err %d)</span><span style="color:#b0b">\n</span><span style="color:#710">"</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">"</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">"</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">"</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">"</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">"</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">"</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->keyType, SEC_OID_UNKNOWN);
|
||||
|
||||
fprintf(stderr, <span style="background-color:hsla(0,100%,50%,0.05)"><span style="color:#710">"</span><span style="color:#D20">Signing with alg = %s (%d)</span><span style="color:#b0b">\n</span><span style="color:#710">"</span></span>,
|
||||
SECOID_FindOIDTagDescription(algTag), algTag);
|
||||
|
||||
rv = SEC_SignData(&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">"</span><span style="color:#D20">sign with Private Key failed (err %d: %s)</span><span style="color:#b0b">\n</span><span style="color:#710">"</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 "My HSM" -libfile ${path_to_pkcs11_file} -dbdir .
|
||||
# Find the token name on your HSM
|
||||
$ modutil -list -dbdir .
|
||||
# find the cert on your token
|
||||
$ certutil -L -h ${token_name} -d .
|
||||
# pass the cert to your signing program
|
||||
$ NSS_Sign_Example "${token_name}:${cert_name}"</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) && 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">"</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">"</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">"</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">"</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">®</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 »</a></p>
|
||||
<p class="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>
|
1893
_preview/fedora/master/en-US/features/Features-TLS.html
Normal file
304
_preview/fedora/master/en-US/index.html
Normal file
1182
_preview/fedora/master/en-US/programming-languages/C.html
Normal file
641
_preview/fedora/master/en-US/programming-languages/CXX.html
Normal file
|
@ -0,0 +1,641 @@
|
|||
<!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 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 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> 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 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> 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> 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 > 0 && n >
|
||||
(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><tr1/*></code> header files. This includes
|
||||
<code>std::tr1::shared_ptr</code> (from
|
||||
<code><tr1/memory></code>) and
|
||||
<code>std::tr1::function</code> (from
|
||||
<code><tr1/functional></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<char></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’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">®</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 »</a></p>
|
||||
<p class="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>
|
356
_preview/fedora/master/en-US/programming-languages/Go.html
Normal file
|
@ -0,0 +1,356 @@
|
|||
<!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> 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 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> 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> 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 <stdin> - 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 <stdin> - 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">®</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 »</a></p>
|
||||
<p class="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>
|
1109
_preview/fedora/master/en-US/programming-languages/Java.html
Normal file
313
_preview/fedora/master/en-US/programming-languages/Python.html
Normal file
|
@ -0,0 +1,313 @@
|
|||
<!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> 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 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> 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> 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">®</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 »</a></p>
|
||||
<p class="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>
|
699
_preview/fedora/master/en-US/programming-languages/Shell.html
Normal file
|
@ -0,0 +1,699 @@
|
|||
<!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> 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 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> 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> 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>“…”</code>.</p>
|
||||
</div>
|
||||
<div class="listingblock">
|
||||
<div class="content">
|
||||
<pre class="CodeRay highlight"><code data-lang="bash">external-program "$arg1" "$arg2"</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="$(mktemp)"
|
||||
|
||||
cleanup () {
|
||||
rm -f -- "$tmpfile"
|
||||
}
|
||||
|
||||
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 <stdin> - 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 "$@" ; 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">®</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 »</a></p>
|
||||
<p class="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>
|
273
_preview/fedora/master/en-US/programming-languages/Vala.html
Normal file
|
@ -0,0 +1,273 @@
|
|||
<!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> 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 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> 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> 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">®</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 »</a></p>
|
||||
<p class="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>
|
428
_preview/fedora/master/en-US/tasks/Tasks-Cryptography.html
Normal file
|
@ -0,0 +1,428 @@
|
|||
<!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> 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 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> 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> 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">®</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 »</a></p>
|
||||
<p class="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>
|
497
_preview/fedora/master/en-US/tasks/Tasks-Descriptors.html
Normal file
|
@ -0,0 +1,497 @@
|
|||
<!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> 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 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> 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> 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><stdio.h></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">®</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 »</a></p>
|
||||
<p class="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>
|
548
_preview/fedora/master/en-US/tasks/Tasks-File_System.html
Normal file
|
@ -0,0 +1,548 @@
|
|||
<!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> 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 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> 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> 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("…​")</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">®</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 »</a></p>
|
||||
<p class="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>
|
425
_preview/fedora/master/en-US/tasks/Tasks-Library_Design.html
Normal file
|
@ -0,0 +1,425 @@
|
|||
<!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> 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 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> 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> 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">®</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 »</a></p>
|
||||
<p class="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>
|
438
_preview/fedora/master/en-US/tasks/Tasks-Packaging.html
Normal file
|
@ -0,0 +1,438 @@
|
|||
<!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> 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 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> 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> 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 "umask 077 && openssl genrsa -out %{tlskey} 2048 2>/dev/null" \
|
||||
%{tlsuser}
|
||||
fi
|
||||
if ! test -e %{tlscert} ; then
|
||||
cn="Automatically generated certificate for the %{tlsuser} service"
|
||||
req_args="-key %{tlskey} -out %{tlscert} -days 7305 -subj \"/CN=$cn/\""
|
||||
su -s /bin/bash \
|
||||
-c "openssl req -new -x509 -extensions usr_cert $req_args" \
|
||||
%{tlsuser}
|
||||
fi
|
||||
fi
|
||||
|
||||
%files
|
||||
%dir %attr(0755,%{tlsuser},%{tlsuser]) %{tlsdir}
|
||||
%ghost %attr(0600,%{tlsuser},%{tlsuser}) %config(noreplace) %{tlskey}
|
||||
%ghost %attr(0644,%{tlsuser},%{tlsuser}) %config(noreplace) %{tlscert}</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 && openssl genrsa -out %{tlskey} 2048 2>/dev/null)
|
||||
chown %{tlsuser} %{tlskey}
|
||||
fi
|
||||
if ! test -e %{tlscert} ; then
|
||||
cn="Automatically generated certificate for the %{tlsuser} service"
|
||||
openssl req -new -x509 -extensions usr_cert \
|
||||
-key %{tlskey} -out %{tlscert} -days 7305 -subj "/CN=$cn/"
|
||||
fi
|
||||
fi
|
||||
|
||||
%files
|
||||
%dir %attr(0755,root,root]) %{tlsdir}
|
||||
%ghost %attr(0600,%{tlsuser},%{tlsuser}) %config(noreplace) %{tlskey}
|
||||
%ghost %attr(0644,root,root) %config(noreplace) %{tlscert}</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">®</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 »</a></p>
|
||||
<p class="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>
|
702
_preview/fedora/master/en-US/tasks/Tasks-Processes.html
Normal file
|
@ -0,0 +1,702 @@
|
|||
<!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> 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 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> 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> 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><defunct></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"><stdlib.h></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">®</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 »</a></p>
|
||||
<p class="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>
|
1031
_preview/fedora/master/en-US/tasks/Tasks-Serialization.html
Normal file
472
_preview/fedora/master/en-US/tasks/Tasks-Temporary_Files.html
Normal file
|
@ -0,0 +1,472 @@
|
|||
<!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> 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 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> 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> 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’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…​)</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">®</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 »</a></p>
|
||||
<p class="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>
|
598
_stylesheets/asciibinder.css
Normal file
|
@ -0,0 +1,598 @@
|
|||
@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; }
|
3
_templates/_css.html.erb
Normal file
|
@ -0,0 +1,3 @@
|
|||
<%- Dir.glob("_stylesheets/*").sort.each do |sheet| -%>
|
||||
<link href="<%= File.join(css_path, File.basename(sheet)) %>" rel="stylesheet" />
|
||||
<%- end -%>
|
31
_templates/_nav.html.erb
Normal file
|
@ -0,0 +1,31 @@
|
|||
<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> <%= 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>
|
187
_templates/page.html.erb
Normal file
|
@ -0,0 +1,187 @@
|
|||
<!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">®</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 »</a></p>
|
||||
<p class="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>
|
75
_topic_map.yml
Normal file
|
@ -0,0 +1,75 @@
|
|||
# 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 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
|
13
en-US/C.adoc
|
@ -1,13 +0,0 @@
|
|||
|
||||
:experimental:
|
||||
|
||||
[[chap-Defensive_Coding-C]]
|
||||
=== The C Programming Language
|
||||
|
||||
include::C-Language.adoc[]
|
||||
|
||||
include::C-Libc.adoc[]
|
||||
|
||||
include::C-Allocators.adoc[]
|
||||
|
||||
include::C-Other.adoc[]
|
|
@ -1,9 +0,0 @@
|
|||
|
||||
:experimental:
|
||||
|
||||
[[chap-Defensive_Coding-CXX]]
|
||||
=== The C++ Programming Language
|
||||
|
||||
include::CXX-Language.adoc[]
|
||||
|
||||
include::CXX-Std.adoc[]
|
|
@ -1,8 +1,6 @@
|
|||
|
||||
:experimental:
|
||||
include::../entities.adoc[]
|
||||
|
||||
Copyright {YEAR} {HOLDER}.
|
||||
Copyright {YEAR} {HOLDER}.
|
||||
|
||||
The text of and illustrations in this document are licensed by Red Hat under a Creative Commons Attribution–Share Alike 3.0 Unported license ("CC-BY-SA"). An explanation of CC-BY-SA is available at link:++http://creativecommons.org/licenses/by-sa/3.0/++[]. The original authors of this document, and Red Hat, designate the Fedora Project as the "Attribution Party" for purposes of CC-BY-SA. In accordance with CC-BY-SA, if you distribute this document or an adaptation of it, you must provide the URL for the original version.
|
||||
|
||||
|
@ -20,4 +18,4 @@ For guidelines on the permitted uses of the Fedora trademarks, refer to link:++h
|
|||
|
||||
*MySQL* is a registered trademark of MySQL AB in the United States, the European Union and other countries.
|
||||
|
||||
All other trademarks are the property of their respective owners.
|
||||
All other trademarks are the property of their respective owners.
|
||||
|
|
|
@ -1,11 +0,0 @@
|
|||
|
||||
:experimental:
|
||||
|
||||
[[chap-Defensive_Coding-Java]]
|
||||
=== The Java Programming Language
|
||||
|
||||
include::Java-Language.adoc[]
|
||||
|
||||
include::Java-LowLevel.adoc[]
|
||||
|
||||
include::Java-SecurityManager.adoc[]
|
|
@ -2,7 +2,7 @@
|
|||
:experimental:
|
||||
|
||||
[[appe-Defensive_Coding-Revision_History]]
|
||||
== Revision History
|
||||
= Revision History
|
||||
|
||||
`1.5`:: Fri Dec 1 2017, Mirek Jahoda (mjahoda@redhat.com)
|
||||
|
||||
|
@ -57,4 +57,4 @@
|
|||
|
||||
`0-1`:: Thu Mar 7 2013, Eric Christensen (sparks@redhat.com)
|
||||
|
||||
* Initial publication.
|
||||
* Initial publication.
|
||||
|
|
|
@ -2,10 +2,10 @@
|
|||
:experimental:
|
||||
|
||||
[[chap-Defensive_Coding-Authentication]]
|
||||
=== Authentication and Authorization
|
||||
= Authentication and Authorization
|
||||
|
||||
[[sect-Defensive_Coding-Authentication-Server]]
|
||||
==== Authenticating Servers
|
||||
== Authenticating Servers
|
||||
|
||||
When connecting to a server, a client has to make sure that it
|
||||
is actually talking to the server it expects. There are two
|
||||
|
@ -47,7 +47,7 @@ crashing the real server by exploiting a denial-of-service
|
|||
vulnerability.
|
||||
|
||||
[[sect-Defensive_Coding-Authentication-Host_based]]
|
||||
==== Host-based Authentication
|
||||
== Host-based Authentication
|
||||
|
||||
Host-based authentication uses access control lists (ACLs) to
|
||||
accept or deny requests from clients. This authentication
|
||||
|
@ -92,7 +92,7 @@ universally correct way to deal with this ambiguity. The
|
|||
behavior of the ACL implementation should be documented.
|
||||
|
||||
[[sect-Defensive_Coding-Authentication-UNIX_Domain]]
|
||||
==== UNIX Domain Socket Authentication
|
||||
== UNIX Domain Socket Authentication
|
||||
|
||||
UNIX domain sockets (with address family
|
||||
`AF_UNIX` or `AF_LOCAL`) are
|
||||
|
@ -127,7 +127,7 @@ information from `/proc/PID/status` is prone
|
|||
to race conditions and insecure.
|
||||
|
||||
[[sect-Defensive_Coding-Authentication-Netlink]]
|
||||
==== `AF_NETLINK` Authentication of Origin
|
||||
== `AF_NETLINK` Authentication of Origin
|
||||
|
||||
Netlink messages are used as a high-performance data transfer
|
||||
mechanism between the kernel and the user space. Traditionally,
|
||||
|
@ -148,4 +148,4 @@ address will be non-zero in such cases.
|
|||
|
||||
Applications should not use `AF_NETLINK`
|
||||
sockets as an IPC mechanism among processes, but prefer UNIX
|
||||
domain sockets for this tasks.
|
||||
domain sockets for this tasks.
|
|
@ -2,7 +2,7 @@
|
|||
:experimental:
|
||||
|
||||
[[chap-Defensive_Coding-HSM]]
|
||||
=== Hardware Security Modules and Smart Cards
|
||||
= Hardware Security Modules and Smart Cards
|
||||
|
||||
Hardware Security Modules (HSMs) are specialized hardware intended
|
||||
to protect private keys on server systems. They store internally
|
||||
|
@ -61,7 +61,7 @@ modules or smart cards. The wrapper PKCS#11 APIs provided by NSS, GnuTLS and
|
|||
engine_pkcs11 (OpenSSL) handle the reinitialization after fork requirement transparently.
|
||||
|
||||
[[sect-Defensive_Coding-HSM-OpenSSL]]
|
||||
==== OpenSSL HSM Support
|
||||
== OpenSSL HSM Support
|
||||
|
||||
OpenSSL does not have native support for PKCS#11. It can
|
||||
provide PKCS#11 support through the OpenSC's project
|
||||
|
@ -81,13 +81,13 @@ and its usage to sign data.
|
|||
|
||||
[source,c]
|
||||
----
|
||||
include::snippets/Features-HSM-OpenSSL.adoc[]
|
||||
include::en-US/snippets/Features-HSM-OpenSSL.adoc[]
|
||||
----
|
||||
|
||||
====
|
||||
|
||||
[[sect-Defensive_Coding-HSM-GNUTLS]]
|
||||
==== GnuTLS HSM Support
|
||||
== GnuTLS HSM Support
|
||||
|
||||
GnuTLS supports PKCS#11 natively. Most of the API functions
|
||||
accepting certificate files, can also accept PKCS#11 URLs, thus
|
||||
|
@ -104,7 +104,7 @@ and its usage to sign data.
|
|||
|
||||
[source,c]
|
||||
----
|
||||
include::snippets/Features-HSM-GNUTLS.adoc[]
|
||||
include::en-US/snippets/Features-HSM-GNUTLS.adoc[]
|
||||
----
|
||||
|
||||
====
|
||||
|
@ -119,13 +119,13 @@ An example PIN callback function is shown below.
|
|||
|
||||
[source,c]
|
||||
----
|
||||
include::snippets/Features-HSM-GNUTLS-PIN.adoc[]
|
||||
include::en-US/snippets/Features-HSM-GNUTLS-PIN.adoc[]
|
||||
----
|
||||
|
||||
====
|
||||
|
||||
[[sect-Defensive_Coding-HSM-NSS]]
|
||||
==== NSS HSM Support
|
||||
== NSS HSM Support
|
||||
|
||||
NSS supports PKCS#11 natively. In fact all NSS crypto operations,
|
||||
including built-in operations, go through PKCS #11 modules. NSS provides
|
||||
|
@ -145,7 +145,7 @@ The following example demonstrates a typical NSS application for signing.
|
|||
|
||||
[source,c]
|
||||
----
|
||||
include::snippets/Features-HSM-NSS.adoc[]
|
||||
include::en-US/snippets/Features-HSM-NSS.adoc[]
|
||||
----
|
||||
|
||||
====
|
||||
|
@ -164,7 +164,7 @@ $ modutil -list -dbdir .
|
|||
$ certutil -L -h ${token_name} -d .
|
||||
# pass the cert to your signing program
|
||||
$ NSS_Sign_Example "${token_name}:${cert_name}"
|
||||
|
||||
|
||||
----
|
||||
|
||||
[[ex-Defensive_Coding-HSM-NSS-PIN]]
|
||||
|
@ -173,7 +173,7 @@ $ NSS_Sign_Example "${token_name}:${cert_name}"
|
|||
|
||||
[source,c]
|
||||
----
|
||||
include::snippets/Features-HSM-NSS-PIN.adoc[]
|
||||
include::en-US/snippets/Features-HSM-NSS-PIN.adoc[]
|
||||
----
|
||||
|
||||
====
|
|
@ -1,9 +1,9 @@
|
|||
|
||||
:experimental:
|
||||
include::entities.adoc[]
|
||||
include::en-US/entities.adoc[]
|
||||
|
||||
[[chap-Defensive_Coding-TLS]]
|
||||
=== Transport Layer Security (TLS)
|
||||
= Transport Layer Security (TLS)
|
||||
|
||||
Transport Layer Security (TLS, formerly Secure Sockets
|
||||
Layer/SSL) is the recommended way to to protect integrity and
|
||||
|
@ -24,7 +24,7 @@ library' documentation.
|
|||
* link:++https://docs.oracle.com/javase/8/docs/technotes/guides/security/jsse/JSSERefGuide.html++[OpenJDK documentation]
|
||||
|
||||
[[sect-Defensive_Coding-TLS-Pitfalls]]
|
||||
==== Common Pitfalls
|
||||
== Common Pitfalls
|
||||
|
||||
TLS implementations are difficult to use, and most of them lack
|
||||
a clean API design. The following sections contain
|
||||
|
@ -62,7 +62,7 @@ duration of the handshake), or use the Linux-specific
|
|||
|
||||
[source,c]
|
||||
----
|
||||
include::snippets/Features-TLS-Nagle.adoc[]
|
||||
include::en-US/snippets/Features-TLS-Nagle.adoc[]
|
||||
----
|
||||
|
||||
====
|
||||
|
@ -94,7 +94,7 @@ cannot be used across `fork` function
|
|||
calls (see <<sect-Defensive_Coding-Tasks-Processes-Fork-Parallel>>).
|
||||
|
||||
[[sect-Defensive_Coding-TLS-OpenSSL]]
|
||||
===== OpenSSL Pitfalls
|
||||
=== OpenSSL Pitfalls
|
||||
|
||||
Some OpenSSL function use *tri-state return
|
||||
values*. Correct error checking is extremely
|
||||
|
@ -133,7 +133,7 @@ due to a connection teardown by the other end).
|
|||
|
||||
[source,c]
|
||||
----
|
||||
include::snippets/Features-TLS-OpenSSL-Errors.adoc[]
|
||||
include::en-US/snippets/Features-TLS-OpenSSL-Errors.adoc[]
|
||||
----
|
||||
|
||||
====
|
||||
|
@ -193,14 +193,14 @@ increase the part of the code base which has to undergo
|
|||
security certification.
|
||||
|
||||
[[sect-Defensive_Coding-TLS-Pitfalls-GnuTLS]]
|
||||
===== GnuTLS Pitfalls
|
||||
=== GnuTLS Pitfalls
|
||||
|
||||
Older versions of GnuTLS had several peculiarities described
|
||||
in previous versions of this guide; as of GnuTLS 3.3.10, these
|
||||
issues are no longer applicable.
|
||||
|
||||
[[sect-Defensive_Coding-TLS-Pitfalls-OpenJDK]]
|
||||
===== OpenJDK Pitfalls
|
||||
=== OpenJDK Pitfalls
|
||||
|
||||
The Java cryptographic framework is highly modular. As a
|
||||
result, when you request an object implementing some
|
||||
|
@ -224,7 +224,7 @@ can block, waiting for more bits to become available in
|
|||
`/dev/random`.
|
||||
|
||||
[[sect-Defensive_Coding-TLS-Pitfalls-NSS]]
|
||||
===== NSS Pitfalls
|
||||
=== NSS Pitfalls
|
||||
|
||||
NSS was not designed to be used by other libraries which can
|
||||
be linked into applications without modifying them. There is
|
||||
|
@ -242,7 +242,7 @@ initialized. This behavior is required by the PKCS#11 API
|
|||
specification.
|
||||
|
||||
[[sect-Defensive_Coding-TLS-Client]]
|
||||
==== TLS Clients
|
||||
== TLS Clients
|
||||
|
||||
Secure use of TLS in a client generally involves all of the
|
||||
following steps. (Individual instructions for specific TLS
|
||||
|
@ -295,7 +295,7 @@ client. These aspects are not yet covered.
|
|||
|
||||
====
|
||||
|
||||
===== Implementation TLS Clients With OpenSSL
|
||||
=== Implementation TLS Clients With OpenSSL
|
||||
|
||||
In the following code, the error handling is only exploratory.
|
||||
Proper error handling is required for production use,
|
||||
|
@ -309,7 +309,7 @@ The OpenSSL library needs explicit initialization (see <<ex-Defensive_Coding-TLS
|
|||
|
||||
[source,c]
|
||||
----
|
||||
include::snippets/Features-TLS-Client-OpenSSL-Init.adoc[]
|
||||
include::en-US/snippets/Features-TLS-Client-OpenSSL-Init.adoc[]
|
||||
|
||||
----
|
||||
|
||||
|
@ -332,7 +332,7 @@ be cumbersome.
|
|||
|
||||
[source,c]
|
||||
----
|
||||
include::snippets/Features-TLS-Client-OpenSSL-CTX.adoc[]
|
||||
include::en-US/snippets/Features-TLS-Client-OpenSSL-CTX.adoc[]
|
||||
----
|
||||
|
||||
====
|
||||
|
@ -380,7 +380,7 @@ name.
|
|||
|
||||
[source,c]
|
||||
----
|
||||
include::snippets/Features-TLS-Client-OpenSSL-Connect.adoc[]
|
||||
include::en-US/snippets/Features-TLS-Client-OpenSSL-Connect.adoc[]
|
||||
----
|
||||
|
||||
====
|
||||
|
@ -397,7 +397,7 @@ transport, using `BIO_set_ssl`.
|
|||
|
||||
[source,c]
|
||||
----
|
||||
include::snippets/Features-TLS-Client-OpenSSL-Connection-Use.adoc[]
|
||||
include::en-US/snippets/Features-TLS-Client-OpenSSL-Connection-Use.adoc[]
|
||||
----
|
||||
|
||||
====
|
||||
|
@ -418,7 +418,7 @@ socket after the connection object has been freed.
|
|||
|
||||
[source,c]
|
||||
----
|
||||
include::snippets/Features-TLS-OpenSSL-Connection-Close.adoc[]
|
||||
include::en-US/snippets/Features-TLS-OpenSSL-Connection-Close.adoc[]
|
||||
----
|
||||
|
||||
====
|
||||
|
@ -433,13 +433,13 @@ because no further TLS connections will be established.
|
|||
|
||||
[source,c]
|
||||
----
|
||||
include::snippets/Features-TLS-OpenSSL-Context-Close.adoc[]
|
||||
include::en-US/snippets/Features-TLS-OpenSSL-Context-Close.adoc[]
|
||||
----
|
||||
|
||||
====
|
||||
|
||||
[[sect-Defensive_Coding-TLS-Client-GnuTLS]]
|
||||
===== Implementation TLS Clients With GnuTLS
|
||||
=== Implementation TLS Clients With GnuTLS
|
||||
|
||||
This section describes how to implement a TLS client with full
|
||||
certificate validation (but without certificate revocation
|
||||
|
@ -456,7 +456,7 @@ CAs (<<ex-Defensive_Coding-TLS-Client-GNUTLS-Credentials>>).
|
|||
|
||||
[source,c]
|
||||
----
|
||||
include::snippets/Features-TLS-Client-GNUTLS-Credentials.adoc[]
|
||||
include::en-US/snippets/Features-TLS-Client-GNUTLS-Credentials.adoc[]
|
||||
----
|
||||
|
||||
====
|
||||
|
@ -466,7 +466,7 @@ object should be freed:
|
|||
|
||||
[source,c]
|
||||
----
|
||||
include::snippets/Features-TLS-GNUTLS-Credentials-Close.adoc[]
|
||||
include::en-US/snippets/Features-TLS-GNUTLS-Credentials-Close.adoc[]
|
||||
----
|
||||
|
||||
During its lifetime, the credentials object can be used to
|
||||
|
@ -486,7 +486,7 @@ This is shown in <<ex-Defensive_Coding-TLS-Client-GNUTLS-Connect>>.
|
|||
|
||||
[source,c]
|
||||
----
|
||||
include::snippets/Features-TLS-Client-GNUTLS-Connect.adoc[]
|
||||
include::en-US/snippets/Features-TLS-Client-GNUTLS-Connect.adoc[]
|
||||
----
|
||||
|
||||
====
|
||||
|
@ -505,7 +505,7 @@ can be omitted if the functionality is not needed.
|
|||
|
||||
[source,c]
|
||||
----
|
||||
include::snippets/Features-TLS-Client-GNUTLS-Verify.adoc[]
|
||||
include::en-US/snippets/Features-TLS-Client-GNUTLS-Verify.adoc[]
|
||||
----
|
||||
|
||||
====
|
||||
|
@ -519,7 +519,7 @@ receiving data, as in <<ex-Defensive_Coding-TLS-GNUTLS-Use>>.
|
|||
|
||||
[source,c]
|
||||
----
|
||||
include::snippets/Features-TLS-GNUTLS-Use.adoc[]
|
||||
include::en-US/snippets/Features-TLS-GNUTLS-Use.adoc[]
|
||||
----
|
||||
|
||||
====
|
||||
|
@ -535,20 +535,20 @@ Finally, the session object can be deallocated using
|
|||
|
||||
[source,c]
|
||||
----
|
||||
include::snippets/Features-TLS-GNUTLS-Disconnect.adoc[]
|
||||
include::en-US/snippets/Features-TLS-GNUTLS-Disconnect.adoc[]
|
||||
----
|
||||
|
||||
====
|
||||
|
||||
[[sect-Defensive_Coding-TLS-Client-OpenJDK]]
|
||||
===== Implementing TLS Clients With OpenJDK
|
||||
=== Implementing TLS Clients With OpenJDK
|
||||
|
||||
The examples below use the following cryptographic-related
|
||||
classes:
|
||||
|
||||
[source,java]
|
||||
----
|
||||
include::snippets/Features-TLS-Client-OpenJDK-Import.adoc[]
|
||||
include::en-US/snippets/Features-TLS-Client-OpenJDK-Import.adoc[]
|
||||
|
||||
----
|
||||
|
||||
|
@ -579,7 +579,7 @@ be supported as a fall-back option. This is shown in <<ex-Defensive_Coding-TLS-C
|
|||
|
||||
[source,java]
|
||||
----
|
||||
include::snippets/Features-TLS-Client-OpenJDK-Context.adoc[]
|
||||
include::en-US/snippets/Features-TLS-Client-OpenJDK-Context.adoc[]
|
||||
----
|
||||
|
||||
====
|
||||
|
@ -595,7 +595,7 @@ connections.
|
|||
|
||||
[source,java]
|
||||
----
|
||||
include::snippets/Features-TLS-OpenJDK-Parameters.adoc[]
|
||||
include::en-US/snippets/Features-TLS-OpenJDK-Parameters.adoc[]
|
||||
----
|
||||
|
||||
====
|
||||
|
@ -606,7 +606,7 @@ separately, and this is only supported by OpenJDK 7 and later:
|
|||
|
||||
[source,java]
|
||||
----
|
||||
include::snippets/Features-TLS-Client-OpenJDK-Hostname.adoc[]
|
||||
include::en-US/snippets/Features-TLS-Client-OpenJDK-Hostname.adoc[]
|
||||
----
|
||||
|
||||
All application protocols can use the
|
||||
|
@ -629,7 +629,7 @@ internal API on OpenJDK 6.
|
|||
|
||||
[source,java]
|
||||
----
|
||||
include::snippets/Features-TLS-Client-OpenJDK-Connect.adoc[]
|
||||
include::en-US/snippets/Features-TLS-Client-OpenJDK-Connect.adoc[]
|
||||
----
|
||||
|
||||
====
|
||||
|
@ -650,12 +650,12 @@ The TLS socket can be used as a regular socket, as shown in
|
|||
|
||||
[source,java]
|
||||
----
|
||||
include::snippets/Features-TLS-Client-OpenJDK-Use.adoc[]
|
||||
include::en-US/snippets/Features-TLS-Client-OpenJDK-Use.adoc[]
|
||||
----
|
||||
|
||||
====
|
||||
|
||||
====== Overriding server certificate validation with OpenJDK 6
|
||||
==== Overriding server certificate validation with OpenJDK 6
|
||||
|
||||
Overriding certificate validation requires a custom trust
|
||||
manager. With OpenJDK 6, the trust manager lacks
|
||||
|
@ -675,7 +675,7 @@ the server certificate is identified by its SHA-256 hash.
|
|||
|
||||
[source,java]
|
||||
----
|
||||
include::snippets/Features-TLS-Client-OpenJDK-MyTrustManager.adoc[]
|
||||
include::en-US/snippets/Features-TLS-Client-OpenJDK-MyTrustManager.adoc[]
|
||||
----
|
||||
|
||||
====
|
||||
|
@ -690,7 +690,7 @@ This trust manager has to be passed to the
|
|||
|
||||
[source,java]
|
||||
----
|
||||
include::snippets/Features-TLS-Client-OpenJDK-Context_For_Cert.adoc[]
|
||||
include::en-US/snippets/Features-TLS-Client-OpenJDK-Context_For_Cert.adoc[]
|
||||
----
|
||||
|
||||
====
|
||||
|
@ -716,7 +716,7 @@ manager object can be used for multiple servers because the
|
|||
server address is available to the trust manager.
|
||||
|
||||
[[sect-Defensive_Coding-TLS-Client-NSS]]
|
||||
===== Implementing TLS Clients With NSS
|
||||
=== Implementing TLS Clients With NSS
|
||||
|
||||
The following code shows how to implement a simple TLS client
|
||||
using NSS. These instructions apply to NSS version 3.14 and
|
||||
|
@ -735,7 +735,7 @@ Using NSS needs several header files, as shown in
|
|||
|
||||
[source,c]
|
||||
----
|
||||
include::snippets/Features-TLS-NSS-Includes.adoc[]
|
||||
include::en-US/snippets/Features-TLS-NSS-Includes.adoc[]
|
||||
----
|
||||
|
||||
====
|
||||
|
@ -761,7 +761,7 @@ load trusted CA certificates from a file.)
|
|||
|
||||
[source,c]
|
||||
----
|
||||
include::snippets/Features-TLS-NSS-Init.adoc[]
|
||||
include::en-US/snippets/Features-TLS-NSS-Init.adoc[]
|
||||
|
||||
----
|
||||
|
||||
|
@ -772,7 +772,7 @@ the following function calls:
|
|||
|
||||
[source,c]
|
||||
----
|
||||
include::snippets/Features-TLS-NSS-Close.adoc[]
|
||||
include::en-US/snippets/Features-TLS-NSS-Close.adoc[]
|
||||
----
|
||||
|
||||
After NSS has been initialized, the TLS connection can be
|
||||
|
@ -808,7 +808,7 @@ certificate is verified and matched against the host name.
|
|||
|
||||
[source,c]
|
||||
----
|
||||
include::snippets/Features-TLS-Client-NSS-Connect.adoc[]
|
||||
include::en-US/snippets/Features-TLS-Client-NSS-Connect.adoc[]
|
||||
----
|
||||
|
||||
====
|
||||
|
@ -822,7 +822,7 @@ the NSPR descriptor to communicate with the server.
|
|||
|
||||
[source,c]
|
||||
----
|
||||
include::snippets/Features-TLS-NSS-Use.adoc[]
|
||||
include::en-US/snippets/Features-TLS-NSS-Use.adoc[]
|
||||
----
|
||||
|
||||
====
|
||||
|
@ -836,14 +836,14 @@ shows how to close the connection.
|
|||
|
||||
[source,c]
|
||||
----
|
||||
include::snippets/Features-TLS-Client-NSS-Close.adoc[]
|
||||
include::en-US/snippets/Features-TLS-Client-NSS-Close.adoc[]
|
||||
|
||||
----
|
||||
|
||||
====
|
||||
|
||||
[[sect-Defensive_Coding-TLS-Client-Python]]
|
||||
===== Implementing TLS Clients With Python
|
||||
=== Implementing TLS Clients With Python
|
||||
|
||||
The Python distribution provides a TLS implementation in the
|
||||
`ssl` module (actually a wrapper around
|
||||
|
@ -877,7 +877,7 @@ certificate returned by `getpeercert`.
|
|||
|
||||
[source,python]
|
||||
----
|
||||
include::snippets/Features-TLS-Client-Python-check_host_name.adoc[]
|
||||
include::en-US/snippets/Features-TLS-Client-Python-check_host_name.adoc[]
|
||||
----
|
||||
|
||||
====
|
||||
|
@ -923,7 +923,7 @@ manually against the host name, by calling the
|
|||
|
||||
[source,python]
|
||||
----
|
||||
include::snippets/Features-TLS-Client-Python-Connect.adoc[]
|
||||
include::en-US/snippets/Features-TLS-Client-Python-Connect.adoc[]
|
||||
----
|
||||
|
||||
====
|
||||
|
@ -933,12 +933,12 @@ be used like a regular socket:
|
|||
|
||||
[source,python]
|
||||
----
|
||||
include::snippets/Features-TLS-Python-Use.adoc[]
|
||||
include::en-US/snippets/Features-TLS-Python-Use.adoc[]
|
||||
----
|
||||
|
||||
Closing the TLS socket is straightforward as well:
|
||||
|
||||
[source,python]
|
||||
----
|
||||
include::snippets/Features-TLS-Python-Close.adoc[]
|
||||
include::en-US/snippets/Features-TLS-Python-Close.adoc[]
|
||||
----
|
61
en-US/images/title_logo.svg
Normal file
|
@ -0,0 +1,61 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
|
||||
<svg
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
version="1.0"
|
||||
width="220"
|
||||
height="70"
|
||||
id="svg6180">
|
||||
<defs
|
||||
id="defs6182" />
|
||||
<g
|
||||
transform="translate(-266.55899,-345.34488)"
|
||||
id="layer1">
|
||||
<path
|
||||
d="m 316.7736,397.581 c 0,0 0,0 -20.53889,0 0.3327,4.45245 3.92157,7.77609 8.70715,7.77609 3.38983,0 6.31456,-1.39616 8.64094,-3.65507 0.46553,-0.46679 0.99726,-0.59962 1.59519,-0.59962 0.79781,0 1.59561,0.39932 2.12692,1.06388 0.3327,0.46553 0.53216,0.99726 0.53216,1.52857 0,0.73118 -0.3327,1.52857 -0.93106,2.12734 -2.7919,2.99052 -7.51086,4.98503 -12.16403,4.98503 -8.44149,0 -15.22074,-6.77967 -15.22074,-15.22158 0,-8.44149 6.58022,-15.22074 15.02171,-15.22074 8.37529,0 14.62323,6.51317 14.62323,15.08749 0,1.26418 -1.12924,2.12861 -2.39258,2.12861 z m -12.23065,-11.76512 c -4.45329,0 -7.51085,2.92473 -8.17499,7.17731 10.03626,0 16.35083,0 16.35083,0 -0.59836,-4.05355 -3.78874,-7.17731 -8.17584,-7.17731 z"
|
||||
id="path11"
|
||||
style="fill:#3c6eb4" />
|
||||
<path
|
||||
d="m 375.46344,410.80807 c -8.44106,0 -15.22074,-6.77968 -15.22074,-15.22159 0,-8.44149 6.77968,-15.22074 15.22074,-15.22074 8.44234,0 15.22159,6.77925 15.22159,15.22074 -4.2e-4,8.44149 -6.77968,15.22159 -15.22159,15.22159 z m 0,-24.65992 c -5.31688,0 -8.77377,4.25427 -8.77377,9.43833 0,5.18364 3.45689,9.43833 8.77377,9.43833 5.31731,0 8.77504,-4.25469 8.77504,-9.43833 -4.2e-4,-5.18406 -3.45773,-9.43833 -8.77504,-9.43833 z"
|
||||
id="path13"
|
||||
style="fill:#3c6eb4" />
|
||||
<path
|
||||
d="m 412.66183,380.36574 c -4.45963,0 -7.40966,1.319 -10.01391,4.62956 l -0.24036,-1.53995 0,0 c -0.20198,-1.60743 -1.57326,-2.84926 -3.23382,-2.84926 -1.80139,0 -3.26206,1.459 -3.26206,3.26081 0,0.003 0,0.005 0,0.008 l 0,0 0,0.003 0,0 0,23.40712 c 0,1.79464 1.46194,3.25743 3.257,3.25743 1.79465,0 3.25744,-1.46279 3.25744,-3.25743 l 0,-12.56209 c 0,-5.71621 4.98502,-8.57432 10.23613,-8.57432 1.59519,0 2.85726,-1.32953 2.85726,-2.92515 0,-1.59561 -1.26207,-2.85726 -2.85768,-2.85726 z"
|
||||
id="path15"
|
||||
style="fill:#3c6eb4" />
|
||||
<path
|
||||
d="m 447.02614,395.58648 c 0.0666,-8.17541 -5.78326,-15.22074 -15.222,-15.22074 -8.44192,0 -15.28779,6.77925 -15.28779,15.22074 0,8.44191 6.64684,15.22159 14.68985,15.22159 4.01434,0 7.62682,-2.06621 9.23846,-4.22518 l 0.79359,2.01434 0,0 c 0.42589,1.13177 1.5176,1.93717 2.7978,1.93717 1.65001,0 2.98756,-1.33671 2.99009,-2.98545 l 0,0 0,-7.80687 0,0 0,-4.1556 z m -15.222,9.43833 c -5.31773,0 -8.77419,-4.25469 -8.77419,-9.43833 0,-5.18406 3.45604,-9.43833 8.77419,-9.43833 5.3173,0 8.77419,4.25427 8.77419,9.43833 0,5.18364 -3.45689,9.43833 -8.77419,9.43833 z"
|
||||
id="path17"
|
||||
style="fill:#3c6eb4" />
|
||||
<path
|
||||
d="m 355.01479,368.3337 c 0,-1.7938 -1.46194,-3.18997 -3.25659,-3.18997 -1.79422,0 -3.25743,1.39659 -3.25743,3.18997 l 0,17.1499 c -1.66097,-3.05756 -5.25026,-5.11786 -9.50495,-5.11786 -8.64052,0 -14.42336,6.51318 -14.42336,15.22074 0,8.70757 5.98229,15.22159 14.42336,15.22159 3.76555,0 7.03057,-1.55429 8.98587,-4.25554 l 0.72317,1.83428 c 0.44782,1.25912 1.64917,2.16024 3.06051,2.16024 1.78621,0 3.24984,-1.45435 3.24984,-3.24815 0,-0.005 0,-0.009 0,-0.0139 l 0,0 0,-38.95128 -4.2e-4,0 z m -15.22116,36.69111 c -5.31731,0 -8.70715,-4.25469 -8.70715,-9.43833 0,-5.18406 3.38984,-9.43833 8.70715,-9.43833 5.31773,0 8.70714,4.0544 8.70714,9.43833 0,5.38309 -3.38941,9.43833 -8.70714,9.43833 z"
|
||||
id="path19"
|
||||
style="fill:#3c6eb4" />
|
||||
<path
|
||||
d="m 287.21553,365.34023 c -0.59414,-0.0877 -1.19966,-0.13198 -1.80097,-0.13198 -6.73118,0 -12.20746,5.4767 -12.20746,12.20788 l 0,3.8132 -3.98903,0 c -1.46237,0 -2.65908,1.19671 -2.65908,2.65781 0,1.46321 1.19671,2.93738 2.65908,2.93738 l 3.98819,0 0,20.46004 c 0,1.79464 1.46236,3.25743 3.25658,3.25743 1.79507,0 3.25744,-1.46279 3.25744,-3.25743 l 0,-20.46004 4.40986,0 c 1.46194,0 2.65823,-1.47417 2.65823,-2.93738 0,-1.46152 -1.19629,-2.65823 -2.65823,-2.65823 l -4.40733,0 0,-3.8132 c 0,-3.13852 2.55323,-6.11469 5.69175,-6.11469 0.28294,0 0.56757,0.0211 0.84672,0.062 1.78031,0.26355 3.4358,-0.54269 3.70019,-2.32342 0.2627,-1.77904 -0.96606,-3.43538 -2.74594,-3.69935 z"
|
||||
id="path21"
|
||||
style="fill:#3c6eb4" />
|
||||
<path
|
||||
d="m 482.01243,363.57426 c 0,-10.06788 -8.16108,-18.22938 -18.22897,-18.22938 -10.06282,0 -18.22179,8.15475 -18.22854,18.21631 l -4.2e-4,-4.2e-4 0,14.1071 4.2e-4,4.2e-4 c 0.005,2.28463 1.85832,4.13409 4.14463,4.13409 0.007,0 0.0127,-8.4e-4 0.0194,-8.4e-4 l 0.001,8.4e-4 14.07083,0 0,0 c 10.06409,-0.004 18.22138,-8.16276 18.22138,-18.22812 z"
|
||||
id="path25"
|
||||
style="fill:#294172" />
|
||||
<path
|
||||
d="m 469.13577,349.66577 c -4.72528,0 -8.55576,3.83049 -8.55576,8.55577 0,0.002 0,0.004 0,0.006 l 0,4.52836 -4.51444,0 c -8.5e-4,0 -8.5e-4,0 -0.001,0 -4.72528,0 -8.55576,3.81193 -8.55576,8.53678 0,4.72528 3.83048,8.55577 8.55576,8.55577 4.72486,0 8.55534,-3.83049 8.55534,-8.55577 0,-0.002 0,-0.004 0,-0.006 l 0,-4.54733 4.51444,0 c 8.5e-4,0 0.001,0 0.002,0 4.72486,0 8.55534,-3.79296 8.55534,-8.51781 0,-4.72528 -3.83048,-8.55577 -8.55534,-8.55577 z m -8.55576,21.63483 c -0.004,2.48998 -2.02446,4.50811 -4.51571,4.50811 -2.49378,0 -4.53426,-2.02193 -4.53426,-4.5157 0,-2.49421 2.04048,-4.55366 4.53426,-4.55366 0.002,0 0.004,4.2e-4 0.006,4.2e-4 l 3.86971,0 c 0.001,0 0.002,-4.2e-4 0.003,-4.2e-4 0.35209,0 0.63799,0.28505 0.63799,0.63715 0,4.2e-4 -4.2e-4,8.4e-4 -4.2e-4,0.001 l 0,3.92284 -4.2e-4,0 z m 8.55534,-8.5448 c -0.001,0 -0.003,0 -0.004,0 l -3.87223,0 c -8.4e-4,0 -0.002,0 -0.002,0 -0.35252,0 -0.63757,-0.28506 -0.63757,-0.63758 l 0,-4.2e-4 0,-3.90343 c 0.004,-2.49083 2.02446,-4.50854 4.51571,-4.50854 2.49378,0 4.53468,2.02193 4.53468,4.51613 4.2e-4,2.49336 -2.04048,4.53384 -4.53426,4.53384 z"
|
||||
id="path29"
|
||||
style="fill:#3c6eb4" />
|
||||
<path
|
||||
d="m 460.58001,362.7558 0,-4.52836 c 0,-0.002 0,-0.004 0,-0.006 0,-4.72528 3.83048,-8.55577 8.55576,-8.55577 0.71685,0 1.22623,0.0805 1.88952,0.25469 0.96774,0.25385 1.75796,1.04618 1.75838,1.96922 4.2e-4,1.11575 -0.80919,1.92621 -2.0194,1.92621 -0.57642,0 -0.78473,-0.11048 -1.62892,-0.11048 -2.49125,0 -4.51149,2.01771 -4.51571,4.50854 l 0,3.90385 0,4.2e-4 c 0,0.35252 0.28505,0.63758 0.63757,0.63758 4.3e-4,0 0.001,0 0.002,0 l 2.96521,0 c 1.10521,0 1.99747,0.88467 1.99832,1.99283 0,1.10816 -0.89353,1.99114 -1.99832,1.99114 l -3.60489,0 0,4.54733 c 0,0.002 0,0.004 0,0.006 0,4.72485 -3.83048,8.55534 -8.55534,8.55534 -0.71684,0 -1.22623,-0.0805 -1.88952,-0.25469 -0.96774,-0.25343 -1.75838,-1.04618 -1.7588,-1.9688 0,-1.11575 0.80919,-1.92663 2.01982,-1.92663 0.576,0 0.78473,0.11048 1.6285,0.11048 2.49125,0 4.51191,-2.01771 4.51613,-4.50811 0,0 0,-3.92368 0,-3.9241 0,-0.35168 -0.2859,-0.63673 -0.63799,-0.63673 -4.3e-4,0 -8.5e-4,0 -0.002,0 l -2.96521,-4.2e-4 c -1.10521,0 -1.99831,-0.88214 -1.99831,-1.9903 -4.3e-4,-1.11533 0.90238,-1.99367 2.01939,-1.99367 l 3.58339,0 0,0 z"
|
||||
id="path31"
|
||||
style="fill:#ffffff" />
|
||||
<path
|
||||
d="m 477.41661,378.55292 2.81558,0 0,0.37898 -1.18152,0 0,2.94935 -0.45254,0 0,-2.94935 -1.18152,0 0,-0.37898 m 3.26144,0 0.67101,0 0.84937,2.26496 0.85381,-2.26496 0.67102,0 0,3.32833 -0.43917,0 0,-2.9226 -0.85828,2.28279 -0.45255,0 -0.85827,-2.28279 0,2.9226 -0.43694,0 0,-3.32833"
|
||||
id="text6223"
|
||||
style="fill:#294172;enable-background:new" />
|
||||
</g>
|
||||
<path
|
||||
d="m 181.98344,61.675273 2.81558,0 0,0.37898 -1.18152,0 0,2.94935 -0.45254,0 0,-2.94935 -1.18152,0 0,-0.37898 m 3.26144,0 0.67101,0 0.84937,2.26496 0.85381,-2.26496 0.67102,0 0,3.32833 -0.43917,0 0,-2.9226 -0.85828,2.28279 -0.45255,0 -0.85827,-2.28279 0,2.9226 -0.43694,0 0,-3.32833"
|
||||
id="path2391"
|
||||
style="fill:#294172;enable-background:new" />
|
||||
</svg>
|
After Width: | Height: | Size: 7.6 KiB |
|
@ -1,5 +1,5 @@
|
|||
|
||||
:experimental:
|
||||
include::en-US/entities.adoc[]
|
||||
|
||||
A Guide to Improving Software Security
|
||||
|
||||
|
@ -12,7 +12,7 @@ programming languages and libraries, and focuses on
|
|||
concrete recommendations.
|
||||
|
||||
--
|
||||
image:Common_Content/images/title_logo.svg[]
|
||||
include::Common_Content/Legal_Notice.adoc[]
|
||||
image::title_logo.svg[]
|
||||
include::en-US/Common_Content/Legal_Notice.adoc[]
|
||||
|
||||
include::Author_Group.adoc[]
|
||||
include::en-US/Author_Group.adoc[]
|
|
@ -1,54 +0,0 @@
|
|||
:doctype: book
|
||||
:toc: left
|
||||
:toclevels: 3
|
||||
:source-highlighter: pygments
|
||||
:pygments-style: friendly
|
||||
:pygments-linenums-mode: inline
|
||||
|
||||
= Defensive Coding Guide
|
||||
|
||||
include::Book_Info.adoc[]
|
||||
|
||||
== Programming Languages
|
||||
|
||||
include::C.adoc[]
|
||||
|
||||
include::CXX.adoc[]
|
||||
|
||||
include::Java.adoc[]
|
||||
|
||||
include::Python.adoc[]
|
||||
|
||||
include::Shell.adoc[]
|
||||
|
||||
include::Go.adoc[]
|
||||
|
||||
include::Vala.adoc[]
|
||||
|
||||
== Specific Programming Tasks
|
||||
|
||||
include::Tasks-Library_Design.adoc[]
|
||||
|
||||
include::Tasks-Descriptors.adoc[]
|
||||
|
||||
include::Tasks-File_System.adoc[]
|
||||
|
||||
include::Tasks-Temporary_Files.adoc[]
|
||||
|
||||
include::Tasks-Processes.adoc[]
|
||||
|
||||
include::Tasks-Serialization.adoc[]
|
||||
|
||||
include::Tasks-Cryptography.adoc[]
|
||||
|
||||
include::Tasks-Packaging.adoc[]
|
||||
|
||||
== Implementing Security Features
|
||||
|
||||
include::Features-Authentication.adoc[]
|
||||
|
||||
include::Features-TLS.adoc[]
|
||||
|
||||
include::Features-HSM.adoc[]
|
||||
|
||||
include::Revision_History.adoc[]
|
|
@ -2,9 +2,9 @@
|
|||
:experimental:
|
||||
|
||||
[[sect-Defensive_Coding-C-Allocators]]
|
||||
==== Memory Allocators
|
||||
== Memory Allocators
|
||||
|
||||
===== `malloc` and Related Functions
|
||||
=== `malloc` and Related Functions
|
||||
|
||||
The C library interfaces for memory allocation are provided by
|
||||
`malloc`, `free` and
|
||||
|
@ -27,7 +27,7 @@ realloc(ptr, size);` is wrong because the memory
|
|||
pointed to by `ptr` leaks in case of an error.
|
||||
|
||||
[[sect-Defensive_Coding-C-Use-After-Free]]
|
||||
====== Use-after-free errors
|
||||
==== Use-after-free errors
|
||||
|
||||
After `free`, the pointer is invalid.
|
||||
Further pointer dereferences are not allowed (and are usually
|
||||
|
@ -43,7 +43,7 @@ compiler may assume that a comparison between the old and new
|
|||
pointer will always return false, so it is impossible to detect
|
||||
movement this way.
|
||||
|
||||
====== Handling Memory Allocation Errors
|
||||
==== Handling Memory Allocation Errors
|
||||
|
||||
Recovering from out-of-memory errors is often difficult or even
|
||||
impossible. In these cases, `malloc` and
|
||||
|
@ -60,7 +60,7 @@ terminate the process. See
|
|||
for related memory allocation concerns.
|
||||
|
||||
[[sect-Defensive_Coding-C-Allocators-alloca]]
|
||||
===== `alloca` and Other Forms of Stack-based Allocation
|
||||
=== `alloca` and Other Forms of Stack-based Allocation
|
||||
|
||||
Allocation on the stack is risky because stack overflow checking
|
||||
is implicit. There is a guard page at the end of the memory
|
||||
|
@ -106,7 +106,7 @@ function, check if `malloc` had been called,
|
|||
and free the buffer as needed.
|
||||
|
||||
[[sect-Defensive_Coding-C-Allocators-Arrays]]
|
||||
===== Array Allocation
|
||||
=== Array Allocation
|
||||
|
||||
When allocating arrays, it is important to check for overflows.
|
||||
The `calloc` function performs such checks.
|
||||
|
@ -119,7 +119,7 @@ greater than `((size_t) -1) / sizeof(T)`. See
|
|||
<<sect-Defensive_Coding-C-Arithmetic>>.
|
||||
|
||||
[[sect-Defensive_Coding-C-Allocators-Custom]]
|
||||
===== Custom Memory Allocators
|
||||
=== Custom Memory Allocators
|
||||
|
||||
Custom memory allocates come in two forms: replacements for
|
||||
`malloc`, and completely different interfaces
|
||||
|
@ -146,7 +146,7 @@ fragmentation. But often, utilization of individual pools
|
|||
is poor, and external fragmentation increases the overall
|
||||
memory usage.
|
||||
|
||||
===== Conservative Garbage Collection
|
||||
=== Conservative Garbage Collection
|
||||
|
||||
Garbage collection can be an alternative to explicit memory
|
||||
management using `malloc` and
|
|
@ -2,13 +2,13 @@
|
|||
:experimental:
|
||||
|
||||
[[sect-Defensive_Coding-C-Language]]
|
||||
==== The Core Language
|
||||
== The Core Language
|
||||
|
||||
C provides no memory safety. Most recommendations in this section
|
||||
deal with this aspect of the language.
|
||||
|
||||
[[sect-Defensive_Coding-C-Undefined]]
|
||||
===== Undefined Behavior
|
||||
=== Undefined Behavior
|
||||
|
||||
Some C constructs are defined to be undefined by the C standard.
|
||||
This does not only mean that the standard does not describe
|
||||
|
@ -28,7 +28,7 @@ Common sources of undefined behavior are:
|
|||
* overflow in signed integer arithmetic
|
||||
|
||||
[[sect-Defensive_Coding-C-Pointers]]
|
||||
===== Recommendations for Pointers and Array Handling
|
||||
=== Recommendations for Pointers and Array Handling
|
||||
|
||||
Always keep track of the size of the array you are working with.
|
||||
Often, code is more obviously correct when you keep a pointer
|
||||
|
@ -56,7 +56,7 @@ The cast silences a compiler warning;
|
|||
|
||||
[source,c]
|
||||
----
|
||||
include::snippets/C-Pointers-remaining.adoc[]
|
||||
include::../snippets/C-Pointers-remaining.adoc[]
|
||||
|
||||
----
|
||||
|
||||
|
@ -74,7 +74,7 @@ because the expression on the left can overflow or wrap around
|
|||
no longer reflects the number of bytes to be processed.
|
||||
|
||||
[[sect-Defensive_Coding-C-Arithmetic]]
|
||||
===== Recommendations for Integer Arithmetic
|
||||
=== Recommendations for Integer Arithmetic
|
||||
|
||||
Overflow in signed integer arithmetic is undefined. This means
|
||||
that it is not possible to check for overflow after it happened,
|
||||
|
@ -86,7 +86,7 @@ see <<ex-Defensive_Coding-C-Arithmetic-bad>>.
|
|||
|
||||
[source,c]
|
||||
----
|
||||
include::snippets/C-Arithmetic-add.adoc[]
|
||||
include::../snippets/C-Arithmetic-add.adoc[]
|
||||
|
||||
----
|
||||
|
||||
|
@ -113,7 +113,7 @@ additions have to be checked in this way.
|
|||
|
||||
[source,c]
|
||||
----
|
||||
include::snippets/C-Arithmetic-add_unsigned.adoc[]
|
||||
include::../snippets/C-Arithmetic-add_unsigned.adoc[]
|
||||
----
|
||||
|
||||
====
|
||||
|
@ -129,7 +129,7 @@ see <<ex-Defensive_Coding-C-Arithmetic-mult>>.
|
|||
|
||||
[source,c]
|
||||
----
|
||||
include::snippets/C-Arithmetic-mult.adoc[]
|
||||
include::../snippets/C-Arithmetic-mult.adoc[]
|
||||
----
|
||||
|
||||
====
|
||||
|
@ -169,7 +169,7 @@ semantics for integer arithmetic, including defined behavior on
|
|||
integer overflow.
|
||||
|
||||
[[sect-Defensive_Coding-C-Globals]]
|
||||
===== Global Variables
|
||||
=== Global Variables
|
||||
|
||||
Global variables should be avoided because they usually lead to
|
||||
thread safety hazards. In any case, they should be declared
|
||||
|
@ -189,7 +189,7 @@ after the `*`, and not before it.
|
|||
|
||||
[source,c]
|
||||
----
|
||||
include::snippets/C-Globals-String_Array.adoc[]
|
||||
include::../snippets/C-Globals-String_Array.adoc[]
|
||||
|
||||
----
|
||||
|
|
@ -1,10 +1,10 @@
|
|||
|
||||
:experimental:
|
||||
|
||||
include::entities.adoc[]
|
||||
include::en-US/entities.adoc[]
|
||||
|
||||
[[sect-Defensive_Coding-C-Libc]]
|
||||
==== The C Standard Library
|
||||
== The C Standard Library
|
||||
|
||||
Parts of the C standard library (and the UNIX and GNU extensions)
|
||||
are difficult to use, so you should avoid them.
|
||||
|
@ -15,7 +15,7 @@ buffers using `malloc` which your code must
|
|||
deallocate explicitly using `free`.
|
||||
|
||||
[[sect-Defensive_Coding-C-Absolutely-Banned]]
|
||||
===== Absolutely Banned Interfaces
|
||||
=== Absolutely Banned Interfaces
|
||||
|
||||
The functions listed below must not be used because they are
|
||||
almost always unsafe. Use the indicated replacements instead.
|
||||
|
@ -58,7 +58,7 @@ statvfs` (limit not actually enforced by the kernel,
|
|||
see `_PC_NAME_MAX` above)
|
||||
|
||||
[[sect-Defensive_Coding-C-Avoid]]
|
||||
===== Functions to Avoid
|
||||
=== Functions to Avoid
|
||||
|
||||
The following string manipulation functions can be used securely
|
||||
in principle, but their use should be avoided because they are
|
||||
|
@ -109,7 +109,7 @@ explicit `envp` argument in process creation
|
|||
(see <<sect-Defensive_Coding-Tasks-Processes-environ>>)
|
||||
|
||||
[[sect-Defensive_Coding-C-String-Functions-Length]]
|
||||
===== String Functions with Explicit Length Arguments
|
||||
=== String Functions with Explicit Length Arguments
|
||||
|
||||
The C run-time library provides string manipulation functions
|
||||
which not just look for NUL characters for string termination,
|
||||
|
@ -118,7 +118,7 @@ However, these functions evolved over a long period of time, and
|
|||
the lengths mean different things depending on the function.
|
||||
|
||||
[[sect-Defensive_Coding-C-Libc-snprintf]]
|
||||
====== `snprintf`
|
||||
==== `snprintf`
|
||||
|
||||
The `snprintf` function provides a way to
|
||||
construct a string in a statically-sized buffer. (If the buffer
|
||||
|
@ -127,7 +127,7 @@ size is allocated on the heap, consider use
|
|||
|
||||
[source,c]
|
||||
----
|
||||
include::snippets/C-String-Functions-snprintf.adoc[]
|
||||
include::../snippets/C-String-Functions-snprintf.adoc[]
|
||||
|
||||
----
|
||||
|
||||
|
@ -157,7 +157,7 @@ invariant. After the loop, the result string is in the
|
|||
|
||||
[source,c]
|
||||
----
|
||||
include::snippets/C-String-Functions-snprintf-incremental.adoc[]
|
||||
include::../snippets/C-String-Functions-snprintf-incremental.adoc[]
|
||||
|
||||
----
|
||||
|
||||
|
@ -176,7 +176,7 @@ Note that it is not permitted to use the same buffer both as
|
|||
the destination and as a source argument.
|
||||
|
||||
[[sect-Defensive_Coding-C-Libc-vsnprintf]]
|
||||
====== `vsnprintf` and Format Strings
|
||||
==== `vsnprintf` and Format Strings
|
||||
|
||||
If you use `vsnprintf` (or
|
||||
`vasprintf` or even
|
||||
|
@ -192,14 +192,14 @@ function (see <<ex-Defensive_Coding-C-String-Functions-format-Attribute>>).
|
|||
|
||||
[source,c]
|
||||
----
|
||||
include::snippets/C-String-Functions-format.adoc[]
|
||||
include::../snippets/C-String-Functions-format.adoc[]
|
||||
|
||||
----
|
||||
|
||||
====
|
||||
|
||||
[[sect-Defensive_Coding-C-Libc-strncpy]]
|
||||
====== `strncpy`
|
||||
==== `strncpy`
|
||||
|
||||
The `strncpy` function does not ensure that
|
||||
the target buffer is null-terminated. A common idiom for
|
||||
|
@ -207,7 +207,7 @@ ensuring NUL termination is:
|
|||
|
||||
[source,c]
|
||||
----
|
||||
include::snippets/C-String-Functions-strncpy.adoc[]
|
||||
include::../snippets/C-String-Functions-strncpy.adoc[]
|
||||
|
||||
----
|
||||
|
||||
|
@ -216,12 +216,12 @@ function for this purpose:
|
|||
|
||||
[source,c]
|
||||
----
|
||||
include::snippets/C-String-Functions-strncat-as-strncpy.adoc[]
|
||||
include::../snippets/C-String-Functions-strncat-as-strncpy.adoc[]
|
||||
|
||||
----
|
||||
|
||||
[[sect-Defensive_Coding-C-Libc-strncat]]
|
||||
====== `strncat`
|
||||
==== `strncat`
|
||||
|
||||
The length argument of the `strncat`
|
||||
function specifies the maximum number of characters copied
|
||||
|
@ -239,7 +239,7 @@ approach similar to <<ex-Defensive_Coding-C-String-Functions-snprintf-incrementa
|
|||
|
||||
[source,c]
|
||||
----
|
||||
include::snippets/C-String-Functions-strncat-emulation.adoc[]
|
||||
include::../snippets/C-String-Functions-strncat-emulation.adoc[]
|
||||
|
||||
----
|
||||
|
||||
|
@ -249,7 +249,7 @@ string:
|
|||
|
||||
[source,c]
|
||||
----
|
||||
include::snippets/C-String-Functions-strncat-merged.adoc[]
|
||||
include::../snippets/C-String-Functions-strncat-merged.adoc[]
|
||||
|
||||
----
|
||||
|
||||
|
@ -262,7 +262,7 @@ It is not possible to use format strings like
|
|||
you use separate buffers. `snprintf` does
|
||||
not support overlapping source and target strings.
|
||||
|
||||
====== `strlcpy` and `strlcat`
|
||||
==== `strlcpy` and `strlcat`
|
||||
|
||||
Some systems support `strlcpy` and
|
||||
`strlcat` functions which behave this way,
|
||||
|
@ -275,12 +275,12 @@ related to the `snprintf` return value.
|
|||
To emulate `strlcat`, use the approach
|
||||
described in <<sect-Defensive_Coding-C-Libc-strncat>>.
|
||||
|
||||
====== ISO C11 Annex K *pass:attributes[{blank}]`_s` functions
|
||||
==== ISO C11 Annex K *pass:attributes[{blank}]`_s` functions
|
||||
|
||||
ISO C11 adds another set of length-checking functions, but GNU
|
||||
libc currently does not implement them.
|
||||
|
||||
====== Other `strn*` and `stpn*` functions
|
||||
==== Other `strn*` and `stpn*` functions
|
||||
|
||||
GNU libc contains additional functions with different variants
|
||||
of length checking. Consult the documentation before using
|
|
@ -2,10 +2,10 @@
|
|||
:experimental:
|
||||
|
||||
[[sect-Defensive_Coding-C-Other]]
|
||||
==== Other C-related Topics
|
||||
== Other C-related Topics
|
||||
|
||||
[[sect-Defensive_Coding-C-Wrapper-Functions]]
|
||||
===== Wrapper Functions
|
||||
=== Wrapper Functions
|
||||
|
||||
Some libraries provide wrappers for standard library functions.
|
||||
Common cases include allocation functions such as
|
||||
|
@ -50,4 +50,4 @@ For other attributes (such as `malloc`),
|
|||
careful analysis and comparison with the compiler documentation
|
||||
is required to check if propagating the attribute is
|
||||
appropriate. Incorrectly applied attributes can result in
|
||||
undesired behavioral changes in the compiled code.
|
||||
undesired behavioral changes in the compiled code.
|
13
en-US/programming-languages/C.adoc
Normal file
|
@ -0,0 +1,13 @@
|
|||
|
||||
:experimental:
|
||||
|
||||
[[chap-Defensive_Coding-C]]
|
||||
= The C Programming Language
|
||||
|
||||
include::en-US/programming-languages/C-Language.adoc[]
|
||||
|
||||
include::en-US/programming-languages/C-Libc.adoc[]
|
||||
|
||||
include::en-US/programming-languages/C-Allocators.adoc[]
|
||||
|
||||
include::en-US/programming-languages/C-Other.adoc[]
|
|
@ -2,12 +2,12 @@
|
|||
:experimental:
|
||||
|
||||
[[sect-Defensive_Coding-CXX-Language]]
|
||||
==== The Core Language
|
||||
== The Core Language
|
||||
|
||||
C++ includes a large subset of the C language. As far as the C
|
||||
subset is used, the recommendations in <<chap-Defensive_Coding-C>> apply.
|
||||
|
||||
===== Array Allocation with `operator new[]`
|
||||
=== Array Allocation with `operator new[]`
|
||||
|
||||
For very large values of `n`, an expression
|
||||
like `new T[n]` can return a pointer to a heap
|
||||
|
@ -43,7 +43,7 @@ untrusted data.
|
|||
See <<sect-Defensive_Coding-C-Allocators-Arrays>>
|
||||
for array allocation advice for C-style memory allocation.
|
||||
|
||||
===== Overloading
|
||||
=== Overloading
|
||||
|
||||
Do not overload functions with versions that have different
|
||||
security characteristics. For instance, do not implement a
|
||||
|
@ -51,7 +51,7 @@ function `strcat` which works on
|
|||
`std::string` arguments. Similarly, do not name
|
||||
methods after such functions.
|
||||
|
||||
===== ABI compatibility and preparing for security updates
|
||||
=== ABI compatibility and preparing for security updates
|
||||
|
||||
A stable binary interface (ABI) is vastly preferred for security
|
||||
updates. Without a stable ABI, all reverse dependencies need
|
||||
|
@ -81,7 +81,7 @@ Compatibility Issues With {cpp}]
|
|||
pointer-to-implementation idiom).
|
||||
|
||||
[[sect-Defensive_Coding-CXX-Language-CXX11]]
|
||||
===== {cpp}0X and {cpp}11 Support
|
||||
=== {cpp}0X and {cpp}11 Support
|
||||
|
||||
GCC offers different language compatibility modes:
|
||||
|
|
@ -2,19 +2,19 @@
|
|||
:experimental:
|
||||
|
||||
[[sect-Defensive_Coding-CXX-Std]]
|
||||
==== The C++ Standard Library
|
||||
== The C++ Standard Library
|
||||
|
||||
The C++ standard library includes most of its C counterpart
|
||||
by reference, see <<sect-Defensive_Coding-C-Libc>>.
|
||||
|
||||
[[sect-Defensive_Coding-CXX-Std-Functions]]
|
||||
===== Functions That Are Difficult to Use
|
||||
=== Functions That Are Difficult to Use
|
||||
|
||||
This section collects functions and function templates which are
|
||||
part of the standard library and are difficult to use.
|
||||
|
||||
[[sect-Defensive_Coding-CXX-Std-Functions-Unpaired_Iterators]]
|
||||
====== Unpaired Iterators
|
||||
==== Unpaired Iterators
|
||||
|
||||
Functions which use output operators or iterators which do not
|
||||
come in pairs (denoting ranges) cannot perform iterator range
|
||||
|
@ -69,7 +69,7 @@ read beyond the end of the input range if the caller is not careful:
|
|||
* `std::mismatch`
|
||||
|
||||
[[sect-Defensive_Coding-CXX-Std-String]]
|
||||
===== String Handling with `std::string`
|
||||
=== String Handling with `std::string`
|
||||
|
||||
The `std::string` class provides a convenient
|
||||
way to handle strings. Unlike C strings,
|
||||
|
@ -142,7 +142,7 @@ does not depend on sharing of the internal character array
|
|||
object anymore.
|
||||
|
||||
[[sect-Defensive_Coding-CXX-Std-Subscript]]
|
||||
===== Containers and `operator[]`
|
||||
=== Containers and `operator[]`
|
||||
|
||||
Many sequence containers similar to `std::vector`
|
||||
provide both `operator[](size_type)` and a
|
||||
|
@ -169,7 +169,7 @@ defined; it returns an arbitrary pointer, but not necessarily
|
|||
the NULL pointer.
|
||||
|
||||
[[sect-Defensive_Coding-CXX-Std-Iterators]]
|
||||
===== Iterators
|
||||
=== Iterators
|
||||
|
||||
Iterators do not perform any bounds checking. Therefore, all
|
||||
functions that work on iterators should accept them in pairs,
|
8
en-US/programming-languages/CXX.adoc
Normal file
|
@ -0,0 +1,8 @@
|
|||
:experimental:
|
||||
|
||||
[[chap-Defensive_Coding-CXX]]
|
||||
= The C++ Programming Language
|
||||
|
||||
include::en-US/programming-languages/CXX-Language.adoc[]
|
||||
|
||||
include::en-US/programming-languages/CXX-Std.adoc[]
|
|
@ -2,12 +2,12 @@
|
|||
:experimental:
|
||||
|
||||
[[chap-Defensive_Coding-Go]]
|
||||
=== The Go Programming Language
|
||||
= The Go Programming Language
|
||||
|
||||
This chapter contains language-specific recommendations for Go.
|
||||
|
||||
[[chap-Defensive_Coding-Go-Memory_Safety]]
|
||||
==== Memory Safety
|
||||
== Memory Safety
|
||||
|
||||
Go provides memory safety, but only if the program is not executed
|
||||
in parallel (that is, `GOMAXPROCS` is not larger than
|
||||
|
@ -28,7 +28,7 @@ finalizers are executed concurrently, potentially interleaved with
|
|||
the rest of the program.
|
||||
|
||||
[[chap-Defensive_Coding-Go-Error_Handling]]
|
||||
==== Error Handling
|
||||
== Error Handling
|
||||
|
||||
Only a few common operations (such as pointer dereference, integer
|
||||
division, array subscripting) trigger exceptions in Go, called
|
||||
|
@ -53,7 +53,7 @@ details.
|
|||
|
||||
[source,go]
|
||||
----
|
||||
include::snippets/Go-Error_Handling-Regular.adoc[]
|
||||
include::../snippets/Go-Error_Handling-Regular.adoc[]
|
||||
|
||||
----
|
||||
|
||||
|
@ -73,14 +73,14 @@ returning both data and an error at the same time.
|
|||
|
||||
[source,go]
|
||||
----
|
||||
include::snippets/Go-Error_Handling-IO.adoc[]
|
||||
include::../snippets/Go-Error_Handling-IO.adoc[]
|
||||
|
||||
----
|
||||
|
||||
====
|
||||
|
||||
[[chap-Defensive_Coding-Go-Garbage_Collector]]
|
||||
==== Garbage Collector
|
||||
== Garbage Collector
|
||||
|
||||
Older Go releases (before Go 1.3) use a conservative garbage
|
||||
collector without blacklisting. This means that data blobs can
|
||||
|
@ -92,7 +92,7 @@ may be possible to trigger it deliberately—it is unlikely to occur
|
|||
spontaneously.
|
||||
|
||||
[[chap-Defensive_Coding-Go-Marshaling]]
|
||||
==== Marshaling and Unmarshaling
|
||||
== Marshaling and Unmarshaling
|
||||
|
||||
Several packages in the `encoding` hierarchy
|
||||
provide support for serialization and deserialization. The usual
|
|
@ -2,7 +2,7 @@
|
|||
:experimental:
|
||||
|
||||
[[sect-Defensive_Coding-Java-Language]]
|
||||
==== The Core Language
|
||||
== The Core Language
|
||||
|
||||
Implementations of the Java programming language provide strong
|
||||
memory safety, even in the presence of data races in concurrent
|
||||
|
@ -11,7 +11,7 @@ from occurring, unless certain low-level features are used; see
|
|||
<<sect-Defensive_Coding-Java-LowLevel>>.
|
||||
|
||||
[[sect-Defensive_Coding-Java-Language-ReadArray]]
|
||||
===== Increasing Robustness when Reading Arrays
|
||||
=== Increasing Robustness when Reading Arrays
|
||||
|
||||
External data formats often include arrays, and the data is
|
||||
stored as an integer indicating the number of array elements,
|
||||
|
@ -31,7 +31,7 @@ data, implementing an exponential growth policy. See the
|
|||
|
||||
[source,java]
|
||||
----
|
||||
include::snippets/Java-Language-ReadArray.adoc[]
|
||||
include::../snippets/Java-Language-ReadArray.adoc[]
|
||||
|
||||
----
|
||||
|
||||
|
@ -42,7 +42,7 @@ default constructor and do not specify a size hint. You can
|
|||
simply add the elements to the collection as you read them.
|
||||
|
||||
[[sect-Defensive_Coding-Java-Language-Resources]]
|
||||
===== Resource Management
|
||||
=== Resource Management
|
||||
|
||||
Unlike C++, Java does not offer destructors which can deallocate
|
||||
resources in a predictable fashion. All resource management has
|
||||
|
@ -62,7 +62,7 @@ possible and should not throw any exceptions.
|
|||
|
||||
[source,java]
|
||||
----
|
||||
include::snippets/Java-Finally.adoc[]
|
||||
include::../snippets/Java-Finally.adoc[]
|
||||
|
||||
----
|
||||
|
||||
|
@ -87,7 +87,7 @@ used instead. The Java compiler will automatically insert the
|
|||
|
||||
[source,java]
|
||||
----
|
||||
include::snippets/Java-TryWithResource.adoc[]
|
||||
include::../snippets/Java-TryWithResource.adoc[]
|
||||
|
||||
----
|
||||
|
||||
|
@ -109,7 +109,7 @@ unchecked) exceptions, but this should not be a reason to ignore
|
|||
any actual error conditions.
|
||||
|
||||
[[sect-Defensive_Coding-Java-Language-Finalizers]]
|
||||
===== Finalizers
|
||||
=== Finalizers
|
||||
|
||||
Finalizers can be used a last-resort approach to free resources
|
||||
which would otherwise leak. Finalization is unpredictable,
|
||||
|
@ -157,7 +157,7 @@ implemented by overriding the `finalize()`
|
|||
method, and to custom finalization using reference queues.
|
||||
|
||||
[[sect-Defensive_Coding-Java-Language-Exceptions]]
|
||||
===== Recovering from Exceptions and Errors
|
||||
=== Recovering from Exceptions and Errors
|
||||
|
||||
Java exceptions come in three kinds, all ultimately deriving
|
||||
from `java.lang.Throwable`:
|
||||
|
@ -202,7 +202,7 @@ to predict and can happen at any point and reflect that
|
|||
something went wrong beyond all expectations.
|
||||
|
||||
[[sect-Defensive_Coding-Java-Language-Exceptions-Errors]]
|
||||
====== The Difficulty of Catching Errors
|
||||
==== The Difficulty of Catching Errors
|
||||
|
||||
Errors (that is, exceptions which do not (indirectly) derive
|
||||
from `java.lang.Exception`), have the
|
|
@ -2,10 +2,10 @@
|
|||
:experimental:
|
||||
|
||||
[[sect-Defensive_Coding-Java-LowLevel]]
|
||||
==== Low-level Features of the Virtual Machine
|
||||
== Low-level Features of the Virtual Machine
|
||||
|
||||
[[sect-Defensive_Coding-Java-Reflection]]
|
||||
===== Reflection and Private Parts
|
||||
=== Reflection and Private Parts
|
||||
|
||||
The `setAccessible(boolean)` method of the
|
||||
`java.lang.reflect.AccessibleObject` class
|
||||
|
@ -24,7 +24,7 @@ not happen because all the language-defined checks still apply.)
|
|||
This feature should be avoided if possible.
|
||||
|
||||
[[sect-Defensive_Coding-Java-JNI]]
|
||||
===== Java Native Interface (JNI)
|
||||
=== Java Native Interface (JNI)
|
||||
|
||||
The Java Native Interface allows calling from Java code
|
||||
functions specifically written for this purpose, usually in C or
|
||||
|
@ -75,7 +75,7 @@ beginning of the array.
|
|||
|
||||
[source,java]
|
||||
----
|
||||
include::snippets/Java-JNI-Pointers.adoc[]
|
||||
include::../snippets/Java-JNI-Pointers.adoc[]
|
||||
|
||||
----
|
||||
|
||||
|
@ -133,7 +133,7 @@ is defined, but in C/C++ it is not (for the
|
|||
`jint` and `jlong` types).
|
||||
|
||||
[[sect-Defensive_Coding-Java-MiscUnsafe]]
|
||||
===== `sun.misc.Unsafe`
|
||||
=== `sun.misc.Unsafe`
|
||||
|
||||
The `sun.misc.Unsafe` class is unportable and
|
||||
contains many functions explicitly designed to break Java memory
|
|
@ -2,7 +2,7 @@
|
|||
:experimental:
|
||||
|
||||
[[sect-Defensive_Coding-Java-SecurityManager]]
|
||||
==== Interacting with the Security Manager
|
||||
== Interacting with the Security Manager
|
||||
|
||||
The Java platform is largely implemented in the Java language
|
||||
itself. Therefore, within the same JVM, code runs which is part
|
||||
|
@ -38,7 +38,7 @@ default (including many classes which are part of the OpenJDK
|
|||
implementation).
|
||||
|
||||
[[sect-Defensive_Coding-Java-SecurityManager-Compatible]]
|
||||
===== Security Manager Compatibility
|
||||
=== Security Manager Compatibility
|
||||
|
||||
A lot of code can run without any additional permissions at all,
|
||||
with little changes. The following guidelines should help to
|
||||
|
@ -61,7 +61,7 @@ untrusted code (hopefully in a restricted and secure manner),
|
|||
see <<sect-Defensive_Coding-Java-SecurityManager-Privileged>>.
|
||||
|
||||
[[sect-Defensive_Coding-Java-SecurityManager-Activate]]
|
||||
===== Activating the Security Manager
|
||||
=== Activating the Security Manager
|
||||
|
||||
The usual command to launch a Java application,
|
||||
[command]`java`, does not activate the security manager.
|
||||
|
@ -87,7 +87,7 @@ option).
|
|||
----
|
||||
|
||||
grant {
|
||||
permission java.security.AllPermission;
|
||||
permission java.security.AllPermission;
|
||||
};
|
||||
|
||||
----
|
||||
|
@ -99,7 +99,7 @@ active, and explicit requests to drop privileges will be
|
|||
honored.
|
||||
|
||||
[[sect-Defensive_Coding-Java-SecurityManager-Unprivileged]]
|
||||
===== Reducing Trust in Code
|
||||
=== Reducing Trust in Code
|
||||
|
||||
The <<ex-Defensive_Coding-Java-SecurityManager-Unprivileged>> example
|
||||
shows how to run a piece code of with reduced privileges.
|
||||
|
@ -110,7 +110,7 @@ shows how to run a piece code of with reduced privileges.
|
|||
|
||||
[source,java]
|
||||
----
|
||||
include::snippets/Java-SecurityManager-Unprivileged.adoc[]
|
||||
include::../snippets/Java-SecurityManager-Unprivileged.adoc[]
|
||||
|
||||
----
|
||||
|
||||
|
@ -123,7 +123,7 @@ on all files in the current directory) can be used:
|
|||
|
||||
[source,java]
|
||||
----
|
||||
include::snippets/Java-SecurityManager-CurrentDirectory.adoc[]
|
||||
include::../snippets/Java-SecurityManager-CurrentDirectory.adoc[]
|
||||
|
||||
----
|
||||
|
||||
|
@ -159,7 +159,7 @@ Unfortunately, this affects the virtual machine as a whole, so
|
|||
it is not possible to do this from a library.
|
||||
|
||||
[[sect-Defensive_Coding-Java-SecurityManager-Privileged]]
|
||||
===== Re-gaining Privileges
|
||||
=== Re-gaining Privileges
|
||||
|
||||
Ordinarily, when trusted code is called from untrusted code, it
|
||||
loses its privileges (because of the untrusted stack frames
|
||||
|
@ -208,7 +208,7 @@ shows how to request additional privileges.
|
|||
|
||||
[source,java]
|
||||
----
|
||||
include::snippets/Java-SecurityManager-Privileged.adoc[]
|
||||
include::../snippets/Java-SecurityManager-Privileged.adoc[]
|
||||
|
||||
----
|
||||
|
||||
|
@ -249,7 +249,7 @@ invocation out of the privileged code section, of course.)
|
|||
|
||||
[source,java]
|
||||
----
|
||||
include::snippets/Java-SecurityManager-Callback.adoc[]
|
||||
include::../snippets/Java-SecurityManager-Callback.adoc[]
|
||||
|
||||
----
|
||||
|