Sophie

Sophie

distrib > Fedora > 14 > x86_64 > media > updates > by-pkgid > 762e4b4e451f9de4722602c03fda2c9b > files > 190

python-fedora-0.3.25.1-1.fc14.1.noarch.rpm



<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
  "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml">
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    
    <title>CSRF Protection &mdash; python-fedora v0.3.25.1 documentation</title>
    <link rel="stylesheet" href="_static/default.css" type="text/css" />
    <link rel="stylesheet" href="_static/pygments.css" type="text/css" />
    <script type="text/javascript">
      var DOCUMENTATION_OPTIONS = {
        URL_ROOT:    '',
        VERSION:     '0.3.25.1',
        COLLAPSE_INDEX: false,
        FILE_SUFFIX: '.html',
        HAS_SOURCE:  true
      };
    </script>
    <script type="text/javascript" src="_static/jquery.js"></script>
    <script type="text/javascript" src="_static/underscore.js"></script>
    <script type="text/javascript" src="_static/doctools.js"></script>
    <link rel="search" type="application/opensearchdescription+xml"
          title="Search within python-fedora v0.3.25.1 documentation"
          href="_static/opensearch.xml"/>
    <link rel="top" title="python-fedora v0.3.25.1 documentation" href="index.html" />
    <link rel="up" title="Fedora Services" href="service.html" />
    <link rel="next" title="Authentication to FAS" href="auth.html" />
    <link rel="prev" title="Fedora Services" href="service.html" /> 
  </head>
  <body>
    <div class="related">
      <h3>Navigation</h3>
      <ul>
        <li class="right" style="margin-right: 10px">
          <a href="genindex.html" title="General Index"
             accesskey="I">index</a></li>
        <li class="right" >
          <a href="py-modindex.html" title="Python Module Index"
             >modules</a> |</li>
        <li class="right" >
          <a href="auth.html" title="Authentication to FAS"
             accesskey="N">next</a> |</li>
        <li class="right" >
          <a href="service.html" title="Fedora Services"
             accesskey="P">previous</a> |</li>
        <li><a href="index.html">python-fedora v0.3.25.1 documentation</a> &raquo;</li>
          <li><a href="service.html" accesskey="U">Fedora Services</a> &raquo;</li> 
      </ul>
    </div>  

    <div class="document">
      <div class="documentwrapper">
        <div class="bodywrapper">
          <div class="body">
            
  <div class="section" id="csrf-protection">
<span id="id1"></span><h1>CSRF Protection<a class="headerlink" href="#csrf-protection" title="Permalink to this headline">¶</a></h1>
<table class="docutils field-list" frame="void" rules="none">
<col class="field-name" />
<col class="field-body" />
<tbody valign="top">
<tr class="field"><th class="field-name">Authors:</th><td class="field-body">Toshio Kuratomi</td>
</tr>
<tr class="field"><th class="field-name">Date:</th><td class="field-body">21 February 2009</td>
</tr>
<tr class="field"><th class="field-name">For Version:</th><td class="field-body">0.3.x</td>
</tr>
</tbody>
</table>
<p><a class="reference internal" href="glossary.html#term-csrf"><em class="xref std std-term">CSRF</em></a>, Cross-Site Request Forgery is a technique where a malicious
website can gain access to a Fedora Service by hijacking a currently open
session in a user&#8217;s web browser.  This technique affects identification via SSL
Certificates, cookies, or anything else that the browser sends to the server
automatically when a request to that server is made.  It can take place over
both GET and POST.  GET requests just need to hit a vulnerable URL.  POST
requests require JavaScript to construct the form that is sent to the
vulnerable server.</p>
<div class="admonition note">
<p class="first admonition-title">Note</p>
<p class="last">If you just want to implement this in <a class="reference internal" href="service.html#fedora-services"><em>Fedora Services</em></a>, skip to the
<a class="reference internal" href="#summary-of-changes-per-app">Summary of Changes Per App</a> section</p>
</div>
<div class="section" id="how-csrf-works">
<h2>How CSRF Works<a class="headerlink" href="#how-csrf-works" title="Permalink to this headline">¶</a></h2>
<ol class="arabic simple">
<li>A vulnerable web service allows users to change things on their site using
just a cookie for authentication and submission of a form or by hitting a
URL with an <tt class="docutils literal"><span class="pre">img</span></tt> tag.</li>
<li>A malicious website is crafted that looks harmless but has JavaScript or an
<tt class="docutils literal"><span class="pre">img</span></tt> tag that sends a request to the web service with the form data or
just hits the vulnerable URL.</li>
<li>The user goes somewhere that people who are frequently logged into the site
are at and posts something innocuous that gets people to click on the link
to the malicious website.</li>
<li>When a user who is logged into the vulnerable website clicks on the link,
their web browser loads the page.  It sees the img tag and contacts the
vulnerable website to request the listed URL <em>sending the user&#8217;s
authentication cookie automatically</em>.</li>
<li>The vulnerable server performs the action that the URL requires as the
user whose cookies were sent and the damage is done... typically without
the user knowing any better until much later.</li>
</ol>
</div>
<div class="section" id="how-to-prevent-it">
<h2>How to Prevent It<a class="headerlink" href="#how-to-prevent-it" title="Permalink to this headline">¶</a></h2>
<div class="section" id="theory">
<h3>Theory<a class="headerlink" href="#theory" title="Permalink to this headline">¶</a></h3>
<p>In order to remove this problem we need to have a shared secret between the
user&#8217;s browser and the web site that is only available via the http
request-response.  This secret is required in order for any actions to be
performed on the site.  Because the <a class="reference internal" href="glossary.html#term-same-origin-policy"><em class="xref std std-term">Same Origin Policy</em></a> prevents the
malicious website from reading the web page itself, a shared secret passed in
this manner will prevent the malicious site from performing any actions.
Note that this secret cannot be transferred from the user&#8217;s browser to the
server via a cookie because this is something that the browser does
automatically.  It can, however, be transferred from the server to the browser
via a cookie because the browser prevents scripts from other domains from
<em>reading</em> the cookies.</p>
</div>
<div class="section" id="practice">
<h3>Practice<a class="headerlink" href="#practice" title="Permalink to this headline">¶</a></h3>
<p>The strategy we&#8217;ve adopted is sometimes called <a class="reference internal" href="glossary.html#term-double-submit"><em class="xref std std-term">double submit</em></a>.  Every
time we POST a form or make a GET request that requires us to be authenticated
we must also submit a token consisting of a hash of the <tt class="docutils literal"><span class="pre">tg-visit</span></tt> to show
the server that we were able to read either the cookie or the response from a
previous request.  We store the token value in a GET or POST parameter named
<tt class="docutils literal"><span class="pre">_csrf_token</span></tt>.  If the server receives the <tt class="docutils literal"><span class="pre">tg-visit</span></tt> without the
<tt class="docutils literal"><span class="pre">_csrf_token</span></tt> parameter, the server renders the user anonymous until the
user clicks another link.</p>
<div class="admonition note">
<p class="first admonition-title">Note</p>
<p class="last">We hash the <tt class="docutils literal"><span class="pre">tg-visit</span></tt> session to make the token because we sometimes
send the token as a parameter in GET requests so it will show up in the
servers http logs.</p>
</div>
<div class="section" id="verifying-the-token">
<h4>Verifying the Token<a class="headerlink" href="#verifying-the-token" title="Permalink to this headline">¶</a></h4>
<p>The <a class="reference internal" href="auth.html#module-fedora.tg.identity.jsonfasprovider1" title="fedora.tg.identity.jsonfasprovider1 (deprecated)"><tt class="xref py py-mod docutils literal"><span class="pre">jsonfasprovider1</span></tt></a> does the work of
verifying that <tt class="docutils literal"><span class="pre">_csrf_token</span></tt> has been set and that it is a valid hash of the
<tt class="docutils literal"><span class="pre">tg-visit</span></tt> token belonging to the user.  The sequence of events to verify a
user&#8217;s identity follows this outline:</p>
<ol class="arabic simple">
<li>If username and password given</li>
</ol>
<blockquote>
<div><ol class="arabic simple">
<li>Verify with the identity provider that the username and password match</li>
</ol>
<blockquote>
<div><ol class="arabic simple">
<li>[YES] authenticate the user</li>
<li>[NO] user is anonymous.</li>
</ol>
</div></blockquote>
</div></blockquote>
<ol class="arabic simple" start="2">
<li>if tg-visit cookie present</li>
</ol>
<blockquote>
<div><ol class="arabic simple">
<li>if session_id from <tt class="docutils literal"><span class="pre">tg-visit</span></tt> is in the db and not expired and
(sha1sum(<tt class="docutils literal"><span class="pre">tg-visit</span></tt>) matches <tt class="docutils literal"><span class="pre">_csrf_token</span></tt> given as a (POST variable
or GET variable)</li>
</ol>
<blockquote>
<div><ol class="arabic simple">
<li>[YES] authenticate the user</li>
<li>[NO] Take user to login page that just requires the user to click a
link.  Clicking the link shows that it&#8217;s not just JavaScript in the
browser attempting to load the page but an actual user.  Once the link
is clicked, the user will have a <tt class="docutils literal"><span class="pre">_csrf_token</span></tt>.  If the link is not
clicked the user is treated as anonymous.</li>
</ol>
</div></blockquote>
<ol class="arabic simple" start="2">
<li>Verify via SSL Certificate</li>
</ol>
<blockquote>
<div><ol class="arabic simple">
<li>SSL Certificate is not revoked and  able to retrieve info for the
username and (sha1sum(<tt class="docutils literal"><span class="pre">tg-visit</span></tt>) matches <tt class="docutils literal"><span class="pre">_csrf_token</span></tt> given as a
POST variable or GET variable)</li>
</ol>
<blockquote>
<div><ol class="arabic simple">
<li>[YES] authenticate the user</li>
<li>[NO] Take user to login page that just requires the user to click a
link.  Clicking the link shows that it&#8217;s not just JavaScript in the
browser attempting to load the page but an actual user.  Once the link
is clicked, the user will have a <tt class="docutils literal"><span class="pre">_csrf_token</span></tt>.  If the link is not
clicked the user is treated as anonymous.</li>
</ol>
</div></blockquote>
</div></blockquote>
</div></blockquote>
<p>This work should mostly happen behind the scenes so the application programmer
does not need to worry about this.</p>
<div class="admonition-see-also admonition seealso">
<p class="first admonition-title">See also</p>
<p class="last">The <a class="reference internal" href="auth.html#module-fedora.tg.identity.jsonfasprovider1" title="fedora.tg.identity.jsonfasprovider1 (deprecated)"><tt class="xref py py-mod docutils literal"><span class="pre">jsonfasprovider1</span></tt></a>
documentation has more information on methods that are provided by the
identity provider in case you do need to tell what the authentication token
is and whether it is missing.</p>
</div>
</div>
<div class="section" id="getting-the-token-into-the-page">
<h4>Getting the Token into the Page<a class="headerlink" href="#getting-the-token-into-the-page" title="Permalink to this headline">¶</a></h4>
<p>Embedding the <a class="reference internal" href="glossary.html#term-csrf"><em class="xref std std-term">CSRF</em></a> token into the URLs that the user can click on is
the other half of this problem.  <a class="reference internal" href="service.html#module-fedora.tg.utils" title="fedora.tg.utils"><tt class="xref py py-mod docutils literal"><span class="pre">fedora.tg.utils</span></tt></a> provides two
functions to make this easier.</p>
<dl class="function">
<dt id="fedora.tg.utils.url">
<tt class="descclassname">fedora.tg.utils.</tt><tt class="descname">url</tt><big>(</big><em>tgpath</em>, <em>tgparams=None</em>, <em>**kwargs</em><big>)</big><a class="headerlink" href="#fedora.tg.utils.url" title="Permalink to this definition">¶</a></dt>
<dd><p>Computes URLs.</p>
<p>This is a replacement for <tt class="xref py py-func docutils literal"><span class="pre">turbogears.controllers.url()</span></tt> (aka
<tt class="xref py py-func docutils literal"><span class="pre">tg.url()</span></tt> in the template).  In addition to the functionality that
<tt class="xref py py-func docutils literal"><span class="pre">tg.url()</span></tt> provides, it adds a token to prevent <a class="reference internal" href="glossary.html#term-csrf"><em class="xref std std-term">CSRF</em></a> attacks.</p>
<table class="docutils field-list" frame="void" rules="none">
<col class="field-name" />
<col class="field-body" />
<tbody valign="top">
<tr class="field"><th class="field-name">Parameters:</th><td class="field-body"><ul class="first simple">
<li><strong>tgpath</strong> &#8211; a list or a string. If the path is absolute (starts
with a &#8220;/&#8221;), the <tt class="xref py py-attr docutils literal"><span class="pre">server.webpath</span></tt>, <span class="target" id="index-0"></span><tt class="xref std std-envvar docutils literal"><span class="pre">SCRIPT_NAME</span></tt> and
the approot of the application are prepended to the path. In order for
the approot to be detected properly, the root object should extend
<tt class="xref py py-class docutils literal"><span class="pre">turbogears.controllers.RootController</span></tt>.</li>
<li><strong>tgparams</strong> &#8211; See param: <tt class="docutils literal"><span class="pre">kwargs</span></tt></li>
<li><strong>kwargs</strong> &#8211; Query parameters for the URL can be passed in as a dictionary
in the second argument <em>or</em> as keyword parameters.  Values which are a
list or a tuple are used to create multiple key-value pairs.</li>
</ul>
</td>
</tr>
<tr class="field"><th class="field-name">Returns:</th><td class="field-body"><p class="first last">The changed path</p>
</td>
</tr>
</tbody>
</table>
<p class="versionadded">
<span class="versionmodified">New in version 0.3.10: </span>Modified from turbogears.controllers.url for <a class="reference internal" href="#csrf-protection"><em>CSRF Protection</em></a></p>
</dd></dl>

<p>This function does everything <tt class="xref py py-func docutils literal"><span class="pre">tg.url()</span></tt> does in the templates.  In
addition it makes sure that <tt class="docutils literal"><span class="pre">_csrf_token</span></tt> is appended to the URL.</p>
<dl class="function">
<dt id="fedora.tg.utils.enable_csrf">
<tt class="descclassname">fedora.tg.utils.</tt><tt class="descname">enable_csrf</tt><big>(</big><big>)</big><a class="headerlink" href="#fedora.tg.utils.enable_csrf" title="Permalink to this definition">¶</a></dt>
<dd><p>A startup function to setup <a class="reference internal" href="#csrf-protection"><em>CSRF Protection</em></a>.</p>
<p>This should be run at application startup.  Code like the following in the
start-APP script or the method in <tt class="file docutils literal"><span class="pre">commands.py</span></tt> that starts it:</p>
<div class="highlight-python"><div class="highlight"><pre><span class="kn">from</span> <span class="nn">turbogears</span> <span class="kn">import</span> <span class="n">startup</span>
<span class="kn">from</span> <span class="nn">fedora.tg.util</span> <span class="kn">import</span> <span class="n">enable_csrf</span>
<span class="n">startup</span><span class="o">.</span><span class="n">call_on_startup</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">enable_csrf</span><span class="p">)</span>
</pre></div>
</div>
<p>If we can get the <a class="reference internal" href="#csrf-protection"><em>CSRF Protection</em></a> into upstream <a class="reference internal" href="glossary.html#term-turbogears"><em class="xref std std-term">TurboGears</em></a>,
we might be able to remove this in the future.</p>
<p class="versionadded">
<span class="versionmodified">New in version 0.3.10: </span>Added to enable <a class="reference internal" href="#csrf-protection"><em>CSRF Protection</em></a></p>
</dd></dl>

<p>This function sets config values to allow <tt class="docutils literal"><span class="pre">_csrf_token</span></tt> to be passed to any
URL on the server and makes <tt class="xref py py-func docutils literal"><span class="pre">turbogears.url()</span></tt> point to our <a class="reference internal" href="#fedora.tg.utils.url" title="fedora.tg.utils.url"><tt class="xref py py-func docutils literal"><span class="pre">url()</span></tt></a>
function.  Once this is run, the <tt class="xref py py-func docutils literal"><span class="pre">tg.url()</span></tt> function you use in the
templates will make any links that use with it contain the <a class="reference internal" href="glossary.html#term-csrf"><em class="xref std std-term">CSRF</em></a>
protecting token.</p>
<div class="section" id="intra-application-links">
<h5>Intra-Application Links<a class="headerlink" href="#intra-application-links" title="Permalink to this headline">¶</a></h5>
<p>We support single sign-on among the web applications we&#8217;ve written for Fedora.
In order for this to continue working with this <a class="reference internal" href="glossary.html#term-csrf"><em class="xref std std-term">CSRF</em></a> protection scheme
we have to add the <tt class="docutils literal"><span class="pre">_csrf_token</span></tt> parameter to links between
<a class="reference internal" href="service.html#fedora-services"><em>Fedora Services</em></a>.  Linking from the PackageDB to Bodhi, for instance,
needs to have the hash appended to the URL for Bodhi.  Our <a class="reference internal" href="#fedora.tg.utils.url" title="fedora.tg.utils.url"><tt class="xref py py-func docutils literal"><span class="pre">url()</span></tt></a>
function is capable of generating these by passing the full URL into the
function like this:</p>
<div class="highlight-python"><pre>&lt;a href="${tg.url('https://admin.fedoraproject.org/updates')}"&gt;Bodhi&lt;/a&gt;</pre>
</div>
<div class="admonition note">
<p class="first admonition-title">Note</p>
<p class="last">You probably already use <tt class="xref py py-func docutils literal"><span class="pre">tg.url()</span></tt> for links within you web app to
support <tt class="xref py py-attr docutils literal"><span class="pre">server.webpath</span></tt>.  Adding <tt class="xref py py-func docutils literal"><span class="pre">tg.url()</span></tt> to external links is
new.  You will likely have to update your application&#8217;s templates to call
<a class="reference internal" href="#fedora.tg.utils.url" title="fedora.tg.utils.url"><tt class="xref py py-func docutils literal"><span class="pre">url()</span></tt></a> on these URLs.</p>
</div>
</div>
</div>
<div class="section" id="logging-in">
<h4>Logging In<a class="headerlink" href="#logging-in" title="Permalink to this headline">¶</a></h4>
<p>Each app&#8217;s <a class="reference internal" href="faswho.html#module-login" title="login: Templates related to logging in and out."><tt class="xref py py-meth docutils literal"><span class="pre">login()</span></tt></a> controller method and templates need to be modified
in several ways.</p>
<div class="section" id="templates">
<span id="csrf-login-template"></span><h5>Templates<a class="headerlink" href="#templates" title="Permalink to this headline">¶</a></h5>
<p>For the templates, python-fedora provides a set of standard templates that can
be used to add the token.</p>
<span class="target" id="module-fedora.tg.templates.genshi"></span><p>Genshi version of templates to make adding certain Fedora widgets easier.</p>
<div class="section" id="module-login.html">
<span id="login-html"></span><h6><a class="reference internal" href="#module-login.html" title="login.html: Templates related to logging in and out."><tt class="xref py py-mod docutils literal"><span class="pre">login.html</span></tt></a><a class="headerlink" href="#module-login.html" title="Permalink to this headline">¶</a></h6>
<p><em>Module author: Toshio Kuratomi &lt;<a class="reference external" href="mailto:tkuratom&#37;&#52;&#48;redhat&#46;com">tkuratom<span>&#64;</span>redhat<span>&#46;</span>com</a>&gt;</em></p>
<p class="versionadded">
<span class="versionmodified">New in version 0.3.10.</span></p>
<dl class="docutils">
<dt>Include this using::</dt>
<dd>&lt;xi:include href=&#8221;${tg.fedora_template(&#8216;login.html&#8217;)}&#8221; /&gt;</dd>
</dl>
<dl class="function">
<dt id="login.html.loginform">
<tt class="descclassname">login.html.</tt><tt class="descname">loginform</tt><big>(</big><span class="optional">[</span><em>message</em><span class="optional">]</span><big>)</big><a class="headerlink" href="#login.html.loginform" title="Permalink to this definition">¶</a></dt>
<dd></dd></dl>

<table class="docutils field-list" frame="void" rules="none">
<col class="field-name" />
<col class="field-body" />
<tbody valign="top">
<tr class="field"><th class="field-name">message:</th><td class="field-body">Any text or elements contained by the &lt;loginform&gt; tag will be shown
as a message to the user.  This is generally used to show status of the
last login attempt (&#8220;Please provide your credentials&#8221;, &#8220;Supplied
credentials were not correct&#8221;, etc)</td>
</tr>
</tbody>
</table>
<p>A match template for the main login form.  This is a <a class="reference internal" href="glossary.html#term-csrf"><em class="xref std std-term">CSRF</em></a> token-aware
login form that will prompt for username and password when no session identity
is present and ask the user to click a link if they merely lack a token.</p>
<p>Typical usage would be:</p>
<div class="highlight-python"><pre>&lt;loginform&gt;${message}&lt;/loginform&gt;</pre>
</div>
<dl class="function">
<dt id="login.html.logintoolitem">
<tt class="descclassname">login.html.</tt><tt class="descname">logintoolitem</tt><big>(</big><em>&#64;href=URL</em><big>)</big><a class="headerlink" href="#login.html.logintoolitem" title="Permalink to this definition">¶</a></dt>
<dd></dd></dl>

<table class="docutils field-list" frame="void" rules="none">
<col class="field-name" />
<col class="field-body" />
<tbody valign="top">
<tr class="field"><th class="field-name">&#64;href:</th><td class="field-body">If an href attribute is present for this tag, when a user is
logged in, their username or display_name will be a link to the URL.</td>
</tr>
</tbody>
</table>
<p>A match template to add an entry to a toolbar.  The entry will contain the
user&#8217;s username and a logout button if the user is logged in, a verify login
button if the user has a session cookie but not a <a class="reference internal" href="glossary.html#term-csrf"><em class="xref std std-term">CSRF</em></a> token, or a
login button if the user doesn&#8217;t have a session cookie.</p>
<p>Typical usage looks like this:</p>
<div class="highlight-python"><pre>&lt;ul class="toolbar" id="#main-toolbar"&gt;
  &lt;logintoolitem href="${tg.url('/users/info')}" /&gt;
&lt;/ul&gt;</pre>
</div>
</div>
<div class="section" id="module-jsglobals.html">
<span id="jsglobals-html"></span><h6><a class="reference internal" href="#module-jsglobals.html" title="jsglobals.html: Templates to get information into javascript"><tt class="xref py py-mod docutils literal"><span class="pre">jsglobals.html</span></tt></a><a class="headerlink" href="#module-jsglobals.html" title="Permalink to this headline">¶</a></h6>
<p><em>Module author: Toshio Kuratomi &lt;<a class="reference external" href="mailto:tkuratom&#37;&#52;&#48;redhat&#46;com">tkuratom<span>&#64;</span>redhat<span>&#46;</span>com</a>&gt;</em></p>
<p class="versionadded">
<span class="versionmodified">New in version 0.3.10.</span></p>
<dl class="docutils">
<dt>Include this using::</dt>
<dd>&lt;xi:include href=&#8221;${tg.fedora_template(&#8216;jsglobals.html&#8217;)}&#8221; /&gt;</dd>
</dl>
<dl class="function">
<dt id="jsglobals.html.jsglobals">
<tt class="descclassname">jsglobals.html.</tt><tt class="descname">jsglobals</tt><big>(</big><big>)</big><a class="headerlink" href="#jsglobals.html.jsglobals" title="Permalink to this definition">¶</a></dt>
<dd></dd></dl>

<p>A match template to add global variables to a page.  Typically, you&#8217;d include
this in your <tt class="file docutils literal"><span class="pre">master.html</span></tt> template and let it be added to every other
page from there.  This adds the following variables in the fedora namespace
for other scripts to access:</p>
<blockquote>
<div><table class="docutils field-list" frame="void" rules="none">
<col class="field-name" />
<col class="field-body" />
<tbody valign="top">
<tr class="field"><th class="field-name">fedora.baseurl:</th><td class="field-body">URL fragment to prepend to any calls to the application.
In a <a class="reference internal" href="glossary.html#term-turbogears"><em class="xref std std-term">TurboGears</em></a> application, this is the scheme, host, and
server.webpath.  Example: <a class="reference external" href="https://admin.fedoraproject.org/pkgdb/">https://admin.fedoraproject.org/pkgdb/</a>.
This may be a relative link.</td>
</tr>
<tr class="field"><th class="field-name" colspan="2">fedora.identity.anonymous:</th></tr>
<tr><td>&nbsp;</td><td class="field-body">If <tt class="docutils literal"><span class="pre">true</span></tt>, there will be no other variables
in the <cite>fedora.identity</cite> namespace.  If <tt class="docutils literal"><span class="pre">false</span></tt>, these variables are
defined:</td>
</tr>
<tr class="field"><th class="field-name" colspan="2">fedora.identity.userid:</th></tr>
<tr><td>&nbsp;</td><td class="field-body">Numeric, unique identifier for the user</td>
</tr>
<tr class="field"><th class="field-name" colspan="2">fedora.identity.username:</th></tr>
<tr><td>&nbsp;</td><td class="field-body">Publically visible unique identifier for the
user</td>
</tr>
<tr class="field"><th class="field-name" colspan="2">fedora.identity.display_name:</th></tr>
<tr><td>&nbsp;</td><td class="field-body">Common human name for the user</td>
</tr>
<tr class="field"><th class="field-name" colspan="2">fedora.identity.token:</th></tr>
<tr><td>&nbsp;</td><td class="field-body">csrf token for this user&#8217;s session to be added to
urls that query the server.</td>
</tr>
</tbody>
</table>
</div></blockquote>
<p>Typical usage would be:</p>
<div class="highlight-python"><pre>&lt;jsglobals /&gt;</pre>
</div>
</div>
<p>Using the &lt;loginform&gt; template will give you a login form that automatically
does several things for you.</p>
<ol class="arabic simple">
<li>The <tt class="docutils literal"><span class="pre">forward_url</span></tt> and <tt class="docutils literal"><span class="pre">previous_url</span></tt> parameters that are passed in
hidden form elements will be run through <tt class="xref py py-func docutils literal"><span class="pre">tg.url()</span></tt> in order to get the
<tt class="docutils literal"><span class="pre">_csrf_token</span></tt> added.</li>
<li>The page will allow &#8220;Click through validation&#8221; of a user when they have a
valid <tt class="docutils literal"><span class="pre">tg-visit</span></tt> but do not have a <tt class="docutils literal"><span class="pre">_csrf_token</span></tt>.</li>
</ol>
<p>Here&#8217;s a complete login.html from the pkgdb to show what this could look
like:</p>
<div class="highlight-python"><pre>&lt;!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
  "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"&gt;
&lt;html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:py="http://genshi.edgewall.org/"
      xmlns:xi="http://www.w3.org/2001/XInclude"&gt;
  &lt;xi:include href="master.html" /&gt;
  &lt;xi:include href="${tg.fedora_template('login.html')}" /&gt;

  &lt;head&gt;
    &lt;meta content="text/html; charset=UTF-8"
    http-equiv="content-type" py:replace="''"/&gt;
    &lt;title&gt;Login to the PackageDB&lt;/title&gt;
  &lt;/head&gt;

  &lt;body&gt;
    &lt;loginform&gt;${message}&lt;/loginform&gt;
  &lt;/body&gt;
&lt;/html&gt;</pre>
</div>
<p>You should notice that this looks like a typical <a class="reference external" href="http://genshi.edgewall.org">genshi</a> template in your
project with two new features.  The <tt class="docutils literal"><span class="pre">&lt;loginform&gt;</span></tt> tag in the body that&#8217;s
defined in <a class="reference internal" href="#module-fedora.tg.templates.genshi" title="fedora.tg.templates.genshi"><tt class="xref py py-mod docutils literal"><span class="pre">fedora.tg.templates.genshi</span></tt></a> is used in the body to pull in
the login formand the <tt class="docutils literal"><span class="pre">&lt;xi:include&gt;</span></tt> of <tt class="file docutils literal"><span class="pre">login.html</span></tt>
uses <tt class="xref py py-func docutils literal"><span class="pre">tg.fedora_template()</span></tt> to load the template from python-fedora.
This function resides in <a class="reference internal" href="service.html#module-fedora.tg.utils" title="fedora.tg.utils"><tt class="xref py py-mod docutils literal"><span class="pre">fedora.tg.utils</span></tt></a> and is added to the
<tt class="docutils literal"><span class="pre">tg</span></tt> template variable when <a class="reference internal" href="#fedora.tg.utils.enable_csrf" title="fedora.tg.utils.enable_csrf"><tt class="xref py py-func docutils literal"><span class="pre">enable_csrf()</span></tt></a> is
called at startup.  It does the following:</p>
<dl class="function">
<dt id="fedora.tg.utils.fedora_template">
<tt class="descclassname">fedora.tg.utils.</tt><tt class="descname">fedora_template</tt><big>(</big><em>template</em>, <em>template_type='genshi'</em><big>)</big><a class="headerlink" href="#fedora.tg.utils.fedora_template" title="Permalink to this definition">¶</a></dt>
<dd><p>Function to return the path to a template.</p>
<table class="docutils field-list" frame="void" rules="none">
<col class="field-name" />
<col class="field-body" />
<tbody valign="top">
<tr class="field"><th class="field-name">Parameters:</th><td class="field-body"><ul class="first simple">
<li><strong>template</strong> &#8211; filename of the template itself.  Ex: login.html</li>
<li><strong>template_type</strong> &#8211; template language we need the template written in
Defaults to &#8216;genshi&#8217;</li>
</ul>
</td>
</tr>
<tr class="field"><th class="field-name">Returns:</th><td class="field-body"><p class="first last">filesystem path to the template</p>
</td>
</tr>
</tbody>
</table>
</dd></dl>

<p>The second match template in <tt class="file docutils literal"><span class="pre">login.html</span></tt> is to help you modify the
login and logout links that appear at the top of a typical application&#8217;s page.
This is an optional change that lets the links display a click-through login
link in addition to the usual login and logout.  To use this, you would follow
the example to add a <tt class="docutils literal"><span class="pre">toolbar</span></tt> with the <tt class="docutils literal"><span class="pre">&lt;logintoolitem&gt;</span></tt> into your master
template.  Here&#8217;s some snippets from a <tt class="file docutils literal"><span class="pre">master.html</span></tt> to illustrate:</p>
<div class="highlight-python"><pre>&lt;!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
  "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"&gt;
&lt;html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:py="http://genshi.edgewall.org/"
      xmlns:xi="http://www.w3.org/2001/XInclude"&gt;

[...]
  &lt;body py:match="body" py:attrs="select('@*')"&gt;
[...]
    &lt;div id="head"&gt;
      &lt;h1&gt;&lt;a href="http://fedoraproject.org/index.html"&gt;Fedora&lt;/a&gt;&lt;/h1&gt;
      &lt;ul class="toolbar" id="#main-toolbar"&gt;
        &lt;logintoolitem href="${tg.url('/users/info')}" /&gt;
      &lt;/ul&gt;
    &lt;/div&gt;
[...]
  &lt;/body&gt;
  &lt;xi:include href="${tg.fedora_template('login.html')}" /&gt;
  &lt;xi:include href="${tg.fedora_template('jsglobals.html')}" /&gt;
&lt;/html&gt;</pre>
</div>
<div class="admonition warning">
<p class="first admonition-title">Warning</p>
<p class="last">Notice that the <tt class="docutils literal"><span class="pre">&lt;xi:include&gt;</span></tt> of <tt class="file docutils literal"><span class="pre">login.html</span></tt> happens after the
<tt class="docutils literal"><span class="pre">&lt;body&gt;</span></tt> tag?  It is important to do that because the <tt class="docutils literal"><span class="pre">&lt;body&gt;</span></tt> tag in
<tt class="file docutils literal"><span class="pre">master.html</span></tt> is a match template just like <tt class="docutils literal"><span class="pre">&lt;logintoolitem&gt;</span></tt>.  In
<a class="reference external" href="http://genshi.edgewall.org">genshi</a>, the order in which match templates are defined is significant.</p>
</div>
<p>If you need to look at these templates to modify them yourself (perhaps to
port them to a different templating language) you can find them in
<tt class="file docutils literal"><span class="pre">fedora/tg/templates/genshi/login.html</span></tt> in the source tarball.</p>
</div>
<div class="section" id="controllers">
<span id="csrf-controller-methods"></span><h5>Controllers<a class="headerlink" href="#controllers" title="Permalink to this headline">¶</a></h5>
<p>Calling <a class="reference internal" href="service.html#fedora-services"><em>Fedora Services</em></a> from JavaScript poses one further problem.
Sometimes the user will not have a current <a class="reference internal" href="glossary.html#term-csrf"><em class="xref std std-term">CSRF</em></a> token and will need to
log in.  When this is done with a username and password there&#8217;s no
problem because the username and password are sufficient to prove the user is
in control of the browser.  However, when using an SSL Certificate, we need
the browser to log in and then use the new <a class="reference internal" href="glossary.html#term-csrf"><em class="xref std std-term">CSRF</em></a> token to show the user
is in control.  Since JavaScript calls are most likely going to request the
information as JSON, we need to provide the token in the dict returned from
<a class="reference internal" href="faswho.html#module-login" title="login: Templates related to logging in and out."><tt class="xref py py-meth docutils literal"><span class="pre">login()</span></tt></a>.  You can either modify your <a class="reference internal" href="faswho.html#module-login" title="login: Templates related to logging in and out."><tt class="xref py py-meth docutils literal"><span class="pre">login()</span></tt></a> method to do that or
use the one provided in <a class="reference internal" href="#fedora.tg.controllers.login" title="fedora.tg.controllers.login"><tt class="xref py py-func docutils literal"><span class="pre">fedora.tg.controllers.login()</span></tt></a>.</p>
<div class="admonition note">
<p class="first admonition-title">Note</p>
<p class="last">Fedora Services do not currently use certificate authentication but doing
it would not take much code.  Working out the security ramifications within
Infrastructure is the main sticking point to turning this on.</p>
</div>
<div class="admonition note">
<p class="first admonition-title">Note</p>
<p class="last">The <a class="reference external" href="https://admin.fedoraproject.org/accounts/">Fedora Account System</a>
has a slightly different login() method.  This is because it has to handle
account expiration, mandatory password resets, and other things tied to the
status of an account.  Other Fedora Services rely on FAS to do this instead
of having to handle it themselves.</p>
</div>
<span class="target" id="module-fedora.tg.controllers"></span><p>Controller functions that are standard across Fedora Applications</p>
<p><em>Module author: Toshio Kuratomi &lt;<a class="reference external" href="mailto:tkuratom&#37;&#52;&#48;redhat&#46;com">tkuratom<span>&#64;</span>redhat<span>&#46;</span>com</a>&gt;</em></p>
<dl class="function">
<dt id="fedora.tg.controllers.login">
<tt class="descclassname">fedora.tg.controllers.</tt><tt class="descname">login</tt><big>(</big><em>forward_url=None</em>, <em>*args</em>, <em>**kwargs</em><big>)</big><a class="headerlink" href="#fedora.tg.controllers.login" title="Permalink to this definition">¶</a></dt>
<dd><p>Page to become authenticated to the Account System.</p>
<p>This shows a small login box to type in your username and password
from the Fedora Account System.</p>
<p>To use this, replace your current login controller method with:</p>
<div class="highlight-python"><div class="highlight"><pre><span class="kn">from</span> <span class="nn">fedora.controllers</span> <span class="kn">import</span> <span class="n">login</span> <span class="k">as</span> <span class="n">fc_login</span>

<span class="nd">@expose</span><span class="p">(</span><span class="n">template</span><span class="o">=</span><span class="s">&#39;yourapp.yourlogintemplate&#39;</span><span class="p">,</span> <span class="n">allow_json</span><span class="o">=</span><span class="bp">True</span><span class="p">)</span>
<span class="k">def</span> <span class="nf">login</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">forward_url</span><span class="o">=</span><span class="bp">None</span><span class="p">,</span> <span class="o">*</span><span class="n">args</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">):</span>
    <span class="n">login_dict</span> <span class="o">=</span> <span class="n">fc_login</span><span class="p">(</span><span class="n">forward_url</span><span class="p">,</span> <span class="n">args</span><span class="p">,</span> <span class="n">kwargs</span><span class="p">)</span>
    <span class="c"># Add anything to the return dict that you need for your app</span>
    <span class="k">return</span> <span class="n">login_dict</span>
</pre></div>
</div>
<table class="docutils field-list" frame="void" rules="none">
<col class="field-name" />
<col class="field-body" />
<tbody valign="top">
<tr class="field"><th class="field-name">Kwarg :</th><td class="field-body">forward_url: The url to send to once authentication succeeds</td>
</tr>
</tbody>
</table>
</dd></dl>

<dl class="function">
<dt id="fedora.tg.controllers.logout">
<tt class="descclassname">fedora.tg.controllers.</tt><tt class="descname">logout</tt><big>(</big><em>url=None</em><big>)</big><a class="headerlink" href="#fedora.tg.controllers.logout" title="Permalink to this definition">¶</a></dt>
<dd><p>Logout from the server.</p>
<p>To use this, replace your current login controller method with:</p>
<div class="highlight-python"><div class="highlight"><pre><span class="kn">from</span> <span class="nn">fedora.controllers</span> <span class="kn">import</span> <span class="n">logout</span> <span class="k">as</span> <span class="n">fc_logout</span>

<span class="nd">@expose</span><span class="p">(</span><span class="n">allow_json</span><span class="o">=</span><span class="bp">True</span><span class="p">)</span>
<span class="k">def</span> <span class="nf">logout</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
    <span class="k">return</span> <span class="n">fc_logout</span><span class="p">()</span>
</pre></div>
</div>
<table class="docutils field-list" frame="void" rules="none">
<col class="field-name" />
<col class="field-body" />
<tbody valign="top">
<tr class="field"><th class="field-name">Parameters:</th><td class="field-body"><strong>url</strong> &#8211; If provided, when the user logs out, they will always be taken
to this url.  This defaults to taking the user to the URL they were
at when they clicked logout.</td>
</tr>
</tbody>
</table>
</dd></dl>

</div>
</div>
</div>
<div class="section" id="ajax">
<h3>AJAX<a class="headerlink" href="#ajax" title="Permalink to this headline">¶</a></h3>
<p>Making JavaScript calls requires that we can get the token and add it to the
URLs we request.  Since JavaScript doesn&#8217;t have a standard library of crypto
functions we provide the token by setting it via a template so we do not have
to calculate it on the client.  This has the added bonus of propagating a
correct token even if we change the hash function later.  Making use of the
token can then be done in ad hoc JavaScript code but is better handled via a
dedicated JavaScript method like the <tt class="xref py py-class docutils literal"><span class="pre">fedora.dojo.BaseClient</span></tt>.</p>
<div class="section" id="template">
<h4>Template<a class="headerlink" href="#template" title="Permalink to this headline">¶</a></h4>
<div class="admonition warning">
<p class="first admonition-title">Warning</p>
<p class="last">Just like <tt class="file docutils literal"><span class="pre">login.html</span></tt>, the <tt class="docutils literal"><span class="pre">&lt;xi:include&gt;</span></tt> tag needs to come after
the <tt class="docutils literal"><span class="pre">&lt;body&gt;</span></tt> tag since they&#8217;re both match templates.</p>
</div>
</div>
<div class="section" id="javascript">
<h4>JavaScript<a class="headerlink" href="#javascript" title="Permalink to this headline">¶</a></h4>
<p>The <tt class="xref py py-class docutils literal"><span class="pre">fedora.dojo.BaseClient</span></tt> class has been modified to send and update
the csrf token that is provided by fedora.identity.token.  It is highly
recommended that you use this library or another like it to make all calls to
the server.  This keeps you from having to deal with adding the <a class="reference internal" href="glossary.html#term-csrf"><em class="xref std std-term">CSRF</em></a>
token to every call yourself.</p>
<p>Here&#8217;s a small bit of sample code:</p>
<div class="highlight-python"><pre>&lt;script type="text/javascript" src="/js/dojo/dojo.js"&gt;&lt;/script&gt;
&lt;script type="text/javascript"&gt;
    dojo.require('fedora.dojo.BaseClient');
    dojo.addOnLoad(function() {
        pkgdb = new fedora.dojo.BaseClient(fedora.baseurl, {
            username: '', password:''});
        pkg_data = pkgdb.start_request('/packages/name/python',
            {req_params: {collectionName: 'Fedora',
                    collectionVersion: 'devel'}});

    });
&lt;/script&gt;</pre>
</div>
</div>
</div>
</div>
<div class="section" id="summary-of-changes-per-app">
<h2>Summary of Changes Per App<a class="headerlink" href="#summary-of-changes-per-app" title="Permalink to this headline">¶</a></h2>
<blockquote>
<div><ul>
<li><p class="first">On startup, run <a class="reference internal" href="#fedora.tg.utils.enable_csrf" title="fedora.tg.utils.enable_csrf"><tt class="xref py py-func docutils literal"><span class="pre">enable_csrf()</span></tt></a>.  This could be
done in a start-APP.py and APP.wsgi scripts.  Code like this will do it:</p>
<div class="highlight-python"><div class="highlight"><pre><span class="kn">from</span> <span class="nn">turbogears</span> <span class="kn">import</span> <span class="n">startup</span>
<span class="kn">from</span> <span class="nn">fedora.tg.utils</span> <span class="kn">import</span> <span class="n">enable_csrf</span>
<span class="n">startup</span><span class="o">.</span><span class="n">call_on_startup</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">enable_csrf</span><span class="p">)</span>
</pre></div>
</div>
</li>
<li><p class="first">Links to other <a class="reference internal" href="service.html#fedora-services"><em>Fedora Services</em></a> in the templates must be run through
the <tt class="xref py py-func docutils literal"><span class="pre">tg.url()</span></tt> method so that the <a class="reference internal" href="glossary.html#term-csrf"><em class="xref std std-term">CSRF</em></a> token can be appended.</p>
</li>
<li><p class="first">You must use an updated login template.  Using the one provided in
python-fedora is possible by changing your login template as shown in the
<a class="reference internal" href="#csrf-login-template"><em>Templates</em></a> section.</p>
</li>
<li><p class="first">Optional: update the master template that shows the Login/Logout Link to
have a &#8220;Verify Login&#8221; button.  You can add one to a toolbar in your
application following the instructions in the <a class="reference internal" href="#csrf-login-template"><em>Templates</em></a>
section.</p>
</li>
<li><p class="first">Use an updated identity provider from python-fedora.  At this time, you
need python-fedora 0.3.10 or later which has a
<a class="reference internal" href="auth.html#module-fedora.tg.identity.jsonfasprovider2" title="fedora.tg.identity.jsonfasprovider2"><tt class="xref py py-mod docutils literal"><span class="pre">jsonfasprovider2</span></tt></a> and
<a class="reference internal" href="auth.html#module-fedora.tg.visit.jsonfasvisit2" title="fedora.tg.visit.jsonfasvisit2"><tt class="xref py py-mod docutils literal"><span class="pre">jsonfasvisit2</span></tt></a> that provide <a class="reference internal" href="glossary.html#term-csrf"><em class="xref std std-term">CSRF</em></a> protection.
The original <a class="reference internal" href="auth.html#module-fedora.tg.identity.jsonfasprovider1" title="fedora.tg.identity.jsonfasprovider1 (deprecated)"><tt class="xref py py-mod docutils literal"><span class="pre">jsonfasprovider1</span></tt></a> is provided for
applications that have not yet started using
<a class="reference internal" href="#fedora.tg.utils.enable_csrf" title="fedora.tg.utils.enable_csrf"><tt class="xref py py-func docutils literal"><span class="pre">enable_csrf()</span></tt></a> so you have to make this change in
your configuration file (<tt class="file docutils literal"><span class="pre">APPNAME/config/app.cfg</span></tt>)</p>
</li>
<li><p class="first">Get the <a class="reference internal" href="glossary.html#term-csrf"><em class="xref std std-term">CSRF</em></a> token into your forms and URLs.  The recommended way
to do this is to use <tt class="xref py py-func docutils literal"><span class="pre">tg.url()</span></tt> in your forms for URLs that are local
to the app or are for <a class="reference internal" href="service.html#fedora-services"><em>Fedora Services</em></a>.</p>
</li>
<li><p class="first">Update your <a class="reference internal" href="faswho.html#module-login" title="login: Templates related to logging in and out."><tt class="xref py py-meth docutils literal"><span class="pre">login()</span></tt></a> method to make sure you&#8217;re setting
<tt class="docutils literal"><span class="pre">forward_url</span> <span class="pre">=</span> <span class="pre">request.path_info</span></tt> rather than <tt class="docutils literal"><span class="pre">request.path</span></tt>.  One easy
way to do this is to use the <a class="reference internal" href="#fedora.tg.controllers.login" title="fedora.tg.controllers.login"><tt class="xref py py-meth docutils literal"><span class="pre">login()</span></tt></a> and
<a class="reference internal" href="#fedora.tg.controllers.logout" title="fedora.tg.controllers.logout"><tt class="xref py py-meth docutils literal"><span class="pre">logout()</span></tt></a> as documented in
<a class="reference internal" href="#csrf-controller-methods"><em>Controllers</em></a></p>
</li>
<li><p class="first">Add the token and other identity information so JavaScript can get at it.
Use the <tt class="xref py py-mod docutils literal"><span class="pre">jsglobals</span></tt> template to accomplish
this.</p>
</li>
</ul>
</div></blockquote>
<dl class="docutils">
<dt><strong>This one still needs to be implemented</strong></dt>
<dd><ul class="first last simple">
<li>AJAX calls need to be enhanced to append the CSRF token to the data.  This
is best done using a JavaScript function for this like the
<tt class="xref py py-class docutils literal"><span class="pre">fedora.dojo.BaseClient</span></tt> library.</li>
</ul>
</dd>
</dl>
</div>
</div>


          </div>
        </div>
      </div>
      <div class="sphinxsidebar">
        <div class="sphinxsidebarwrapper">
  <h3><a href="index.html">Table Of Contents</a></h3>
  <ul>
<li><a class="reference internal" href="#">CSRF Protection</a><ul>
<li><a class="reference internal" href="#how-csrf-works">How CSRF Works</a></li>
<li><a class="reference internal" href="#how-to-prevent-it">How to Prevent It</a><ul>
<li><a class="reference internal" href="#theory">Theory</a></li>
<li><a class="reference internal" href="#practice">Practice</a><ul>
<li><a class="reference internal" href="#verifying-the-token">Verifying the Token</a></li>
<li><a class="reference internal" href="#getting-the-token-into-the-page">Getting the Token into the Page</a><ul>
<li><a class="reference internal" href="#intra-application-links">Intra-Application Links</a></li>
</ul>
</li>
<li><a class="reference internal" href="#logging-in">Logging In</a><ul>
<li><a class="reference internal" href="#templates">Templates</a><ul>
<li><a class="reference internal" href="#module-login.html"><tt class="docutils literal"><span class="pre">login.html</span></tt></a></li>
<li><a class="reference internal" href="#module-jsglobals.html"><tt class="docutils literal"><span class="pre">jsglobals.html</span></tt></a></li>
</ul>
</li>
<li><a class="reference internal" href="#controllers">Controllers</a></li>
</ul>
</li>
</ul>
</li>
<li><a class="reference internal" href="#ajax">AJAX</a><ul>
<li><a class="reference internal" href="#template">Template</a></li>
<li><a class="reference internal" href="#javascript">JavaScript</a></li>
</ul>
</li>
</ul>
</li>
<li><a class="reference internal" href="#summary-of-changes-per-app">Summary of Changes Per App</a></li>
</ul>
</li>
</ul>

  <h4>Previous topic</h4>
  <p class="topless"><a href="service.html"
                        title="previous chapter">Fedora Services</a></p>
  <h4>Next topic</h4>
  <p class="topless"><a href="auth.html"
                        title="next chapter">Authentication to FAS</a></p>
  <h3>This Page</h3>
  <ul class="this-page-menu">
    <li><a href="_sources/CSRF.txt"
           rel="nofollow">Show Source</a></li>
  </ul>
<div id="searchbox" style="display: none">
  <h3>Quick search</h3>
    <form class="search" action="search.html" method="get">
      <input type="text" name="q" size="18" />
      <input type="submit" value="Go" />
      <input type="hidden" name="check_keywords" value="yes" />
      <input type="hidden" name="area" value="default" />
    </form>
    <p class="searchtip" style="font-size: 90%">
    Enter search terms or a module, class or function name.
    </p>
</div>
<script type="text/javascript">$('#searchbox').show(0);</script>
        </div>
      </div>
      <div class="clearer"></div>
    </div>
    <div class="related">
      <h3>Navigation</h3>
      <ul>
        <li class="right" style="margin-right: 10px">
          <a href="genindex.html" title="General Index"
             >index</a></li>
        <li class="right" >
          <a href="py-modindex.html" title="Python Module Index"
             >modules</a> |</li>
        <li class="right" >
          <a href="auth.html" title="Authentication to FAS"
             >next</a> |</li>
        <li class="right" >
          <a href="service.html" title="Fedora Services"
             >previous</a> |</li>
        <li><a href="index.html">python-fedora v0.3.25.1 documentation</a> &raquo;</li>
          <li><a href="service.html" >Fedora Services</a> &raquo;</li> 
      </ul>
    </div>
    <div class="footer">
        &copy; Copyright 2007-2011 Red Hat, Inc..
      Last updated on Nov 02, 2011.
      Created using <a href="http://sphinx.pocoo.org/">Sphinx</a> 1.0.7.
    </div>
  </body>
</html>