<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
     xmlns:content="http://purl.org/rss/1.0/modules/content/"
     xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
     xmlns:atom="http://www.w3.org/2005/Atom"
     xmlns:dc="http://purl.org/dc/elements/1.1/"
     xmlns:wfw="http://wellformedweb.org/CommentAPI/"
     >
  <channel>
    <title>Topdog.za.net</title>
    <link>http://www.topdog.za.net</link>
    <description>A bored sysadmin</description>
    <pubDate>Fri, 26 Feb 2016 10:06:56 GMT</pubDate>
    <generator>Blogofile</generator>
    <sy:updatePeriod>hourly</sy:updatePeriod>
    <sy:updateFrequency>1</sy:updateFrequency>
    <item>
      <title>Python modules you should know: PyGPGME</title>
      <link>http://www.topdog.za.net/2012/05/23/python-modules-you-should-know:-pygpgme</link>
      <pubDate>Wed, 23 May 2012 07:40:00 SAST</pubDate>
      <category><![CDATA[Python]]></category>
      <category><![CDATA[PyMYSK]]></category>
      <category><![CDATA[Howto]]></category>
      <guid isPermaLink="true">http://www.topdog.za.net/2012/05/23/python-modules-you-should-know:-pygpgme</guid>
      <description>Python modules you should know: PyGPGME</description>
      <content:encoded><![CDATA[<p>Next in our series of <a href="http://www.topdog.za.net/category/pymysk/"><em>Python modules you should know</em></a>
is PyGPGME. This package lets you sign, verify, encrypt and decrypt messages
using the OpenPGP format. It is built on top of the GNU Privacy Guard and the
<a href="http://www.gnupg.org/related_software/gpgme/index.en.html">GPGME</a> library.</p>
<h2>Home page</h2>
<ul>
<li><a href="https://launchpad.net/pygpgme">https://launchpad.net/pygpgme</a></li>
</ul>
<h2>Use</h2>
<p>PyGPGME is a Python module that lets you sign, verify, encrypt and decrypt messages
using the OpenPGP format.</p>
<h2>Installation</h2>
<p>You need the GPGME library and header files installed to successfully install PyGPGME</p>
<pre><code>pip install PyGPGME
</code></pre>
<h2>Usage</h2>
<p>The documentation for this package is almost non existent i hope my examples will
be able to help at least with getting users started</p>
<h3>Creating a key</h3>
<p>This is similar to running the following command:</p>
<pre><code>gpg --gen-key
</code></pre>
<div class="pygments_murphy"><pre><span class="kn">import</span> <span class="nn">os</span>
<span class="kn">import</span> <span class="nn">gpgme</span>

<span class="n">key_params</span> <span class="o">=</span> <span class="s">&quot;&quot;&quot;</span>
<span class="s">&lt;GnupgKeyParms format=&quot;internal&quot;&gt;</span>
<span class="s">Key-Type: RSA</span>
<span class="s">Key-Length: 2048</span>
<span class="s">Name-Real: Jaja of Opobo</span>
<span class="s">Name-Email: jaja@example.com</span>
<span class="s">Expire-Date: 0</span>
<span class="s">Passphrase: secret</span>
<span class="s">&lt;/GnupgKeyParms&gt;</span>
<span class="s">&quot;&quot;&quot;</span>

<span class="c"># create custom gpg directory</span>
<span class="n">gpghome</span> <span class="o">=</span> <span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">expanduser</span><span class="p">(</span><span class="s">&#39;~/gpghome&#39;</span><span class="p">)</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">exists</span><span class="p">(</span><span class="n">gpghome</span><span class="p">):</span>
    <span class="n">os</span><span class="o">.</span><span class="n">mkdir</span><span class="p">(</span><span class="n">gpghome</span><span class="p">,</span> <span class="mo">0700</span><span class="p">)</span>

<span class="c"># set the environment to custom gpg directory</span>
<span class="n">os</span><span class="o">.</span><span class="n">environ</span><span class="p">[</span><span class="s">&#39;GNUPGHOME&#39;</span><span class="p">]</span> <span class="o">=</span> <span class="n">gpghome</span>
<span class="c"># create a blank configuration file</span>
<span class="k">with</span> <span class="nb">open</span><span class="p">(</span><span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="n">gpghome</span><span class="p">,</span> <span class="s">&#39;gpg.conf&#39;</span><span class="p">),</span> <span class="s">&#39;wv&#39;</span><span class="p">)</span> <span class="k">as</span> <span class="n">handle</span><span class="p">:</span>
    <span class="n">handle</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="s">&#39;&#39;</span><span class="p">)</span>

<span class="c"># create a context</span>
<span class="n">ctx</span> <span class="o">=</span> <span class="n">gpgme</span><span class="o">.</span><span class="n">Context</span><span class="p">()</span>
<span class="c"># create the key using key_params</span>
<span class="n">result</span> <span class="o">=</span> <span class="n">ctx</span><span class="o">.</span><span class="n">genkey</span><span class="p">(</span><span class="n">key_params</span><span class="p">)</span>
<span class="c"># get the key</span>
<span class="n">key</span> <span class="o">=</span> <span class="n">ctx</span><span class="o">.</span><span class="n">get_key</span><span class="p">(</span><span class="n">result</span><span class="o">.</span><span class="n">fpr</span><span class="p">,</span> <span class="bp">True</span><span class="p">)</span>
<span class="p">[</span><span class="n">uid</span><span class="p">]</span> <span class="o">=</span> <span class="n">key</span><span class="o">.</span><span class="n">uids</span>
<span class="c"># print key name and email</span>
<span class="k">print</span> <span class="n">uid</span><span class="o">.</span><span class="n">name</span><span class="p">,</span> <span class="n">uid</span><span class="o">.</span><span class="n">email</span>
</pre></div>

<h3>Exporting a key</h3>
<p>This is similar to running the following command:</p>
<pre><code>gpg --export [UID]
</code></pre>
<div class="pygments_murphy"><pre><span class="kn">import</span> <span class="nn">os</span>
<span class="kn">import</span> <span class="nn">gpgme</span>
<span class="kn">from</span> <span class="nn">io</span> <span class="kn">import</span> <span class="n">BytesIO</span>

<span class="c"># set the environment to custom gpg directory</span>
<span class="n">gpghome</span> <span class="o">=</span> <span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">expanduser</span><span class="p">(</span><span class="s">&#39;~/gpghome&#39;</span><span class="p">)</span>
<span class="n">os</span><span class="o">.</span><span class="n">environ</span><span class="p">[</span><span class="s">&#39;GNUPGHOME&#39;</span><span class="p">]</span> <span class="o">=</span> <span class="n">gpghome</span>

<span class="c"># create a context</span>
<span class="n">ctx</span> <span class="o">=</span> <span class="n">gpgme</span><span class="o">.</span><span class="n">Context</span><span class="p">()</span>
<span class="n">ctx</span><span class="o">.</span><span class="n">armor</span> <span class="o">=</span> <span class="bp">True</span>
<span class="n">keydata</span> <span class="o">=</span> <span class="n">BytesIO</span><span class="p">()</span>
<span class="p">[</span><span class="n">key</span><span class="p">]</span> <span class="o">=</span> <span class="n">ctx</span><span class="o">.</span><span class="n">keylist</span><span class="p">()</span>
<span class="n">ctx</span><span class="o">.</span><span class="n">export</span><span class="p">(</span><span class="n">key</span><span class="o">.</span><span class="n">subkeys</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span><span class="o">.</span><span class="n">keyid</span><span class="p">,</span> <span class="n">keydata</span><span class="p">)</span>
<span class="k">print</span> <span class="n">keydata</span><span class="o">.</span><span class="n">getvalue</span><span class="p">()</span>
</pre></div>

<h3>Importing a key</h3>
<p>This is similar to running the following command:</p>
<pre><code>gpg --import [Filename]
</code></pre>
<div class="pygments_murphy"><pre><span class="kn">import</span> <span class="nn">os</span>
<span class="kn">import</span> <span class="nn">gpgme</span>
<span class="kn">import</span> <span class="nn">urllib2</span>

<span class="c"># set the environment to custom gpg directory</span>
<span class="n">gpghome</span> <span class="o">=</span> <span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">expanduser</span><span class="p">(</span><span class="s">&#39;~/gpghome&#39;</span><span class="p">)</span>
<span class="n">os</span><span class="o">.</span><span class="n">environ</span><span class="p">[</span><span class="s">&#39;GNUPGHOME&#39;</span><span class="p">]</span> <span class="o">=</span> <span class="n">gpghome</span>

<span class="c"># create a context</span>
<span class="n">ctx</span> <span class="o">=</span> <span class="n">gpgme</span><span class="o">.</span><span class="n">Context</span><span class="p">()</span>
<span class="c"># Download a public key</span>
<span class="n">handle</span> <span class="o">=</span> <span class="n">urllib2</span><span class="o">.</span><span class="n">urlopen</span><span class="p">(</span><span class="s">&#39;http://repo.baruwa.org/RPM-GPG-KEY-BARUWA&#39;</span><span class="p">)</span>
<span class="c"># Import the key</span>
<span class="n">_</span> <span class="o">=</span> <span class="n">ctx</span><span class="o">.</span><span class="n">import_</span><span class="p">(</span><span class="n">handle</span><span class="p">)</span>
<span class="c"># Get key and print out keyID</span>
<span class="n">key</span> <span class="o">=</span> <span class="n">ctx</span><span class="o">.</span><span class="n">get_key</span><span class="p">(</span><span class="s">&#39;4BA17AC7&#39;</span><span class="p">)</span>
<span class="k">print</span> <span class="s">&quot;Imported key ID: &quot;</span><span class="p">,</span> <span class="n">key</span><span class="o">.</span><span class="n">uids</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span><span class="o">.</span><span class="n">uid</span>
</pre></div>

<h3>Delete a key</h3>
<p>This is similar to running the following command:</p>
<pre><code>gpg --delete-key UID
</code></pre>
<div class="pygments_murphy"><pre><span class="kn">import</span> <span class="nn">os</span>
<span class="kn">import</span> <span class="nn">gpgme</span>

<span class="c"># set the environment to custom gpg directory</span>
<span class="n">gpghome</span> <span class="o">=</span> <span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">expanduser</span><span class="p">(</span><span class="s">&#39;~/gpghome&#39;</span><span class="p">)</span>
<span class="n">os</span><span class="o">.</span><span class="n">environ</span><span class="p">[</span><span class="s">&#39;GNUPGHOME&#39;</span><span class="p">]</span> <span class="o">=</span> <span class="n">gpghome</span>

<span class="c"># create a context</span>
<span class="n">ctx</span> <span class="o">=</span> <span class="n">gpgme</span><span class="o">.</span><span class="n">Context</span><span class="p">()</span>
<span class="c"># Get the public key we just imported</span>
<span class="n">key</span> <span class="o">=</span> <span class="n">ctx</span><span class="o">.</span><span class="n">get_key</span><span class="p">(</span><span class="s">&#39;4BA17AC7&#39;</span><span class="p">)</span>
<span class="c"># Delete the key</span>
<span class="n">ctx</span><span class="o">.</span><span class="n">delete</span><span class="p">(</span><span class="n">key</span><span class="p">)</span>
</pre></div>

<h3>Sign and verify text</h3>
<p>This is similar to running the following commands:</p>
<pre><code>gpg -s (or --sign) [Data]
gpg [--verify] [Data]
</code></pre>
<div class="pygments_murphy"><pre><span class="kn">import</span> <span class="nn">os</span>
<span class="kn">import</span> <span class="nn">gpgme</span>
<span class="kn">from</span> <span class="nn">io</span> <span class="kn">import</span> <span class="n">BytesIO</span>

<span class="c"># set the environment to custom gpg directory</span>
<span class="n">gpghome</span> <span class="o">=</span> <span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">expanduser</span><span class="p">(</span><span class="s">&#39;~/gpghome&#39;</span><span class="p">)</span>
<span class="n">os</span><span class="o">.</span><span class="n">environ</span><span class="p">[</span><span class="s">&#39;GNUPGHOME&#39;</span><span class="p">]</span> <span class="o">=</span> <span class="n">gpghome</span>
<span class="c"># allow our passphrase callback to work</span>
<span class="k">del</span> <span class="n">os</span><span class="o">.</span><span class="n">environ</span><span class="p">[</span><span class="s">&#39;GPG_AGENT_INFO&#39;</span><span class="p">]</span>

<span class="c"># passphrase callback function</span>
<span class="k">def</span> <span class="nf">passphrase_cb</span><span class="p">(</span><span class="n">uid_hint</span><span class="p">,</span> <span class="n">passphrase_info</span><span class="p">,</span> <span class="n">prev_was_bad</span><span class="p">,</span> <span class="n">fd</span><span class="p">):</span>
    <span class="s">&quot;pass phrase callback&quot;</span>
    <span class="n">os</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="n">fd</span><span class="p">,</span> <span class="n">b</span><span class="s">&#39;secret</span><span class="se">\\</span><span class="s">n&#39;</span><span class="p">)</span>

<span class="c"># create a context</span>
<span class="n">ctx</span> <span class="o">=</span> <span class="n">gpgme</span><span class="o">.</span><span class="n">Context</span><span class="p">()</span>
<span class="n">ctx</span><span class="o">.</span><span class="n">armor</span> <span class="o">=</span> <span class="bp">True</span>
<span class="p">[</span><span class="n">key</span><span class="p">]</span> <span class="o">=</span> <span class="n">ctx</span><span class="o">.</span><span class="n">keylist</span><span class="p">()</span>
<span class="n">ctx</span><span class="o">.</span><span class="n">signers</span> <span class="o">=</span> <span class="p">[</span><span class="n">key</span><span class="p">]</span>
<span class="n">ctx</span><span class="o">.</span><span class="n">passphrase_cb</span> <span class="o">=</span> <span class="n">passphrase_cb</span>

<span class="c"># sign the data</span>
<span class="n">plaintext</span> <span class="o">=</span> <span class="n">BytesIO</span><span class="p">(</span><span class="n">b</span><span class="s">&#39;Text to be signed</span><span class="se">\\</span><span class="s">n&#39;</span><span class="p">)</span>
<span class="n">signature</span> <span class="o">=</span> <span class="n">BytesIO</span><span class="p">()</span>
<span class="n">signed</span> <span class="o">=</span> <span class="n">ctx</span><span class="o">.</span><span class="n">sign</span><span class="p">(</span><span class="n">plaintext</span><span class="p">,</span> <span class="n">signature</span><span class="p">,</span> <span class="n">gpgme</span><span class="o">.</span><span class="n">SIG_MODE_DETACH</span><span class="p">)</span>

<span class="c"># rewind files</span>
<span class="n">_</span> <span class="o">=</span> <span class="n">signature</span><span class="o">.</span><span class="n">seek</span><span class="p">(</span><span class="mi">0</span><span class="p">)</span>
<span class="n">_</span> <span class="o">=</span> <span class="n">plaintext</span><span class="o">.</span><span class="n">seek</span><span class="p">(</span><span class="mi">0</span><span class="p">)</span>

<span class="c"># Verify signature</span>
<span class="n">sigs</span> <span class="o">=</span> <span class="n">ctx</span><span class="o">.</span><span class="n">verify</span><span class="p">(</span><span class="n">signature</span><span class="p">,</span> <span class="n">plaintext</span><span class="p">,</span> <span class="bp">None</span><span class="p">)</span>
<span class="k">if</span> <span class="n">sigs</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span><span class="o">.</span><span class="n">fpr</span> <span class="o">==</span> <span class="n">key</span><span class="o">.</span><span class="n">subkeys</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span><span class="o">.</span><span class="n">fpr</span><span class="p">:</span>
    <span class="k">print</span> <span class="s">&quot;Signature verified&quot;</span>
    <span class="k">print</span> <span class="n">sigs</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span><span class="o">.</span><span class="n">fpr</span><span class="p">,</span> <span class="n">key</span><span class="o">.</span><span class="n">subkeys</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span><span class="o">.</span><span class="n">fpr</span>
<span class="k">else</span><span class="p">:</span>
    <span class="k">print</span> <span class="s">&quot;Signature verification failed&quot;</span>
</pre></div>

<h3>Encrypt and Decrypt text</h3>
<p>This is similar to running the following commands:</p>
<pre><code>gpg -e Recipient [Data]
gpg [-d] [Data]
</code></pre>
<div class="pygments_murphy"><pre><span class="kn">import</span> <span class="nn">os</span>
<span class="kn">import</span> <span class="nn">gpgme</span>
<span class="kn">from</span> <span class="nn">io</span> <span class="kn">import</span> <span class="n">BytesIO</span>

<span class="c"># set the environment to custom gpg directory</span>
<span class="n">gpghome</span> <span class="o">=</span> <span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">expanduser</span><span class="p">(</span><span class="s">&#39;~/gpghome&#39;</span><span class="p">)</span>
<span class="n">os</span><span class="o">.</span><span class="n">environ</span><span class="p">[</span><span class="s">&#39;GNUPGHOME&#39;</span><span class="p">]</span> <span class="o">=</span> <span class="n">gpghome</span>
<span class="c"># allow our passphrase callback to work</span>
<span class="k">del</span> <span class="n">os</span><span class="o">.</span><span class="n">environ</span><span class="p">[</span><span class="s">&#39;GPG_AGENT_INFO&#39;</span><span class="p">]</span>

<span class="n">recipient_params</span> <span class="o">=</span> <span class="s">&quot;&quot;&quot;</span>
<span class="s">&lt;GnupgKeyParms format=&quot;internal&quot;&gt;</span>
<span class="s">Key-Type: RSA</span>
<span class="s">Key-Length: 2048</span>
<span class="s">Name-Real: Nana of itsikiri</span>
<span class="s">Name-Email: nana@example.com</span>
<span class="s">Expire-Date: 0</span>
<span class="s">Passphrase: secret</span>
<span class="s">&lt;/GnupgKeyParms&gt;</span>
<span class="s">&quot;&quot;&quot;</span>

<span class="c"># passphrase callback function</span>
<span class="k">def</span> <span class="nf">passphrase_cb</span><span class="p">(</span><span class="n">uid_hint</span><span class="p">,</span> <span class="n">passphrase_info</span><span class="p">,</span> <span class="n">prev_was_bad</span><span class="p">,</span> <span class="n">fd</span><span class="p">):</span>
    <span class="s">&quot;pass phrase callback&quot;</span>
    <span class="n">os</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="n">fd</span><span class="p">,</span> <span class="n">b</span><span class="s">&#39;secret</span><span class="se">\\</span><span class="s">n&#39;</span><span class="p">)</span>

<span class="c"># create a context</span>
<span class="n">ctx</span> <span class="o">=</span> <span class="n">gpgme</span><span class="o">.</span><span class="n">Context</span><span class="p">()</span>
<span class="n">ctx</span><span class="o">.</span><span class="n">armor</span> <span class="o">=</span> <span class="bp">True</span>
<span class="c"># create a recipient&#39;s key</span>
<span class="n">result</span> <span class="o">=</span> <span class="n">ctx</span><span class="o">.</span><span class="n">genkey</span><span class="p">(</span><span class="n">recipient_params</span><span class="p">)</span>
<span class="n">recipient</span> <span class="o">=</span> <span class="n">ctx</span><span class="o">.</span><span class="n">get_key</span><span class="p">(</span><span class="n">result</span><span class="o">.</span><span class="n">fpr</span><span class="p">,</span> <span class="bp">True</span><span class="p">)</span>

<span class="n">plaintext</span> <span class="o">=</span> <span class="n">BytesIO</span><span class="p">(</span><span class="n">b</span><span class="s">&#39;Very Secret text</span><span class="se">\\</span><span class="s">n&#39;</span><span class="p">)</span>
<span class="n">ciphertext</span> <span class="o">=</span> <span class="n">BytesIO</span><span class="p">()</span>
<span class="n">ctx</span><span class="o">.</span><span class="n">encrypt</span><span class="p">([</span><span class="n">recipient</span><span class="p">],</span> <span class="n">gpgme</span><span class="o">.</span><span class="n">ENCRYPT_ALWAYS_TRUST</span><span class="p">,</span> <span class="n">plaintext</span><span class="p">,</span> <span class="n">ciphertext</span><span class="p">)</span>

<span class="c"># rewind files</span>
<span class="n">_</span> <span class="o">=</span> <span class="n">ciphertext</span><span class="o">.</span><span class="n">seek</span><span class="p">(</span><span class="mi">0</span><span class="p">)</span>
<span class="n">_</span> <span class="o">=</span> <span class="n">plaintext</span> <span class="o">=</span> <span class="n">BytesIO</span><span class="p">()</span>
<span class="n">ctx</span><span class="o">.</span><span class="n">passphrase_cb</span> <span class="o">=</span> <span class="n">passphrase_cb</span>
<span class="n">ctx</span><span class="o">.</span><span class="n">decrypt</span><span class="p">(</span><span class="n">ciphertext</span><span class="p">,</span> <span class="n">plaintext</span><span class="p">)</span>
<span class="k">print</span> <span class="s">&quot;The decrypted text is: &quot;</span><span class="p">,</span> <span class="n">plaintext</span><span class="o">.</span><span class="n">getvalue</span><span class="p">()</span>
</pre></div>

<h3>List keys</h3>
<p>This is similar to running the following command:</p>
<pre><code>gpg --list-keys
</code></pre>
<div class="pygments_murphy"><pre><span class="kn">import</span> <span class="nn">os</span>
<span class="kn">import</span> <span class="nn">gpgme</span>

<span class="c"># set the environment to custom gpg directory</span>
<span class="n">gpghome</span> <span class="o">=</span> <span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">expanduser</span><span class="p">(</span><span class="s">&#39;~/gpghome&#39;</span><span class="p">)</span>
<span class="n">os</span><span class="o">.</span><span class="n">environ</span><span class="p">[</span><span class="s">&#39;GNUPGHOME&#39;</span><span class="p">]</span> <span class="o">=</span> <span class="n">gpghome</span>

<span class="c"># create a context</span>
<span class="n">ctx</span> <span class="o">=</span> <span class="n">gpgme</span><span class="o">.</span><span class="n">Context</span><span class="p">()</span>
<span class="c"># iterate key list</span>
<span class="k">for</span> <span class="n">key</span> <span class="ow">in</span> <span class="n">ctx</span><span class="o">.</span><span class="n">keylist</span><span class="p">():</span>
    <span class="k">for</span> <span class="n">uid</span> <span class="ow">in</span> <span class="n">key</span><span class="o">.</span><span class="n">uids</span><span class="p">:</span>
        <span class="k">print</span> <span class="n">uid</span><span class="o">.</span><span class="n">uid</span>
</pre></div>

<h3>List secret keys</h3>
<p>This is similar to running the following command:</p>
<pre><code>gpg --list-secret-keys
</code></pre>
<div class="pygments_murphy"><pre><span class="kn">import</span> <span class="nn">os</span>
<span class="kn">import</span> <span class="nn">gpgme</span>

<span class="c"># set the environment to custom gpg directory</span>
<span class="n">gpghome</span> <span class="o">=</span> <span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">expanduser</span><span class="p">(</span><span class="s">&#39;~/gpghome&#39;</span><span class="p">)</span>
<span class="n">os</span><span class="o">.</span><span class="n">environ</span><span class="p">[</span><span class="s">&#39;GNUPGHOME&#39;</span><span class="p">]</span> <span class="o">=</span> <span class="n">gpghome</span>

<span class="c"># create a context</span>
<span class="n">ctx</span> <span class="o">=</span> <span class="n">gpgme</span><span class="o">.</span><span class="n">Context</span><span class="p">()</span>
<span class="c"># iterate secret key list</span>
<span class="k">for</span> <span class="n">key</span> <span class="ow">in</span> <span class="n">ctx</span><span class="o">.</span><span class="n">keylist</span><span class="p">(</span><span class="bp">None</span><span class="p">,</span> <span class="bp">True</span><span class="p">):</span>
    <span class="k">for</span> <span class="n">uid</span> <span class="ow">in</span> <span class="n">key</span><span class="o">.</span><span class="n">uids</span><span class="p">:</span>
        <span class="k">print</span> <span class="n">uid</span><span class="o">.</span><span class="n">uid</span>
</pre></div>

<h2>And there is more.</h2>
<p>For more GPG operations you can perform look at the API</p>
<div class="pygments_murphy"><pre><span class="kn">import</span> <span class="nn">gpgme</span>
<span class="n">help</span><span class="p">(</span><span class="n">gpgme</span><span class="p">)</span>
</pre></div>]]></content:encoded>
    </item>
    <item>
      <title>Python modules you should know: pydkim</title>
      <link>http://www.topdog.za.net/2012/05/08/python-modules-you-should-know:-pydkim</link>
      <pubDate>Tue, 08 May 2012 16:40:00 SAST</pubDate>
      <category><![CDATA[Python]]></category>
      <category><![CDATA[PyMYSK]]></category>
      <category><![CDATA[Howto]]></category>
      <guid isPermaLink="true">http://www.topdog.za.net/2012/05/08/python-modules-you-should-know:-pydkim</guid>
      <description>Python modules you should know: pydkim</description>
      <content:encoded><![CDATA[<p>Next in our series of <a href="http://www.topdog.za.net/category/pymysk/"><em>Python modules you should know</em></a>
is pydkim. This package is used to sign and verify email according to the <a href="http://dkim.org/">DKIM</a>
standards from within Python programs.</p>
<h2>Home page</h2>
<ul>
<li><a href="http://hewgill.com/pydkim/">http://hewgill.com/pydkim/</a></li>
</ul>
<h2>Use</h2>
<p>The pydkim module is a Python module that implements DKIM (DomainKeys Identified Mail) email signing
and verification.</p>
<p>DomainKeys Identified Mail (DKIM) lets an organization take responsibility for a message that is in
transit. Technically DKIM provides a method for validating a domain name identity that is associated
with a message through cryptographic authentication.</p>
<p>Although DKIM is implemented in most MTA's, in some cases you have a setup where you do not want to
run and manage an SMTP server yourself say for example if your Python application uses <a href="http://docs.amazonwebservices.com/ses/latest/DeveloperGuide/DKIM.html">Amazon SES</a> to send out email. So you
can use pydkim within your email generation code to sign your messages before passing them to SES.</p>
<h2>Installation</h2>
<pre><code>pip install pydkim
</code></pre>
<h2>Usage</h2>
<p>The package provides a command line interface as well as a Python Class.</p>
<h3>Python Class</h3>
<p>Sign a message</p>
<div class="pygments_murphy"><pre><span class="kn">from</span> <span class="nn">email.message</span> <span class="kn">import</span> <span class="n">Message</span>

<span class="kn">from</span> <span class="nn">dkim</span> <span class="kn">import</span> <span class="n">sign</span>

<span class="n">body</span> <span class="o">=</span> <span class="s">&quot;&quot;&quot;Hi There,</span>

<span class="s">This is a simple message that will be signed by pydkim</span>

<span class="s">--The signer</span>
<span class="s">&quot;&quot;&quot;</span>
<span class="c"># compose a simple message</span>
<span class="n">msg</span> <span class="o">=</span> <span class="n">Message</span><span class="p">()</span>
<span class="n">msg</span><span class="p">[</span><span class="s">&#39;From&#39;</span><span class="p">]</span> <span class="o">=</span> <span class="s">&#39;Sender &lt;sender@topdog-software.com&gt;&#39;</span>
<span class="n">msg</span><span class="p">[</span><span class="s">&#39;To&#39;</span><span class="p">]</span> <span class="o">=</span> <span class="s">&#39;Recipient &lt;recipient@example.com&gt;&#39;</span>
<span class="n">msg</span><span class="p">[</span><span class="s">&#39;Subject&#39;</span><span class="p">]</span> <span class="o">=</span> <span class="s">&#39;Test message&#39;</span>
<span class="n">msg</span><span class="o">.</span><span class="n">set_payload</span><span class="p">(</span><span class="n">body</span><span class="p">)</span>

<span class="c"># sign the message</span>
<span class="n">private_key</span> <span class="o">=</span> <span class="nb">open</span><span class="p">(</span><span class="s">&#39;default.pem&#39;</span><span class="p">)</span><span class="o">.</span><span class="n">read</span><span class="p">()</span>
<span class="n">headers</span> <span class="o">=</span> <span class="p">[</span><span class="s">&#39;To&#39;</span><span class="p">,</span> <span class="s">&#39;From&#39;</span><span class="p">,</span> <span class="s">&#39;Subject&#39;</span><span class="p">]</span>
<span class="n">email</span> <span class="o">=</span> <span class="n">msg</span><span class="o">.</span><span class="n">as_string</span><span class="p">()</span>
<span class="n">sig</span> <span class="o">=</span> <span class="n">sign</span><span class="p">(</span><span class="n">email</span><span class="p">,</span> <span class="s">&#39;default&#39;</span><span class="p">,</span> <span class="s">&#39;topdog-software.com&#39;</span><span class="p">,</span> <span class="n">private_key</span><span class="p">,</span> <span class="n">include_headers</span><span class="o">=</span><span class="n">headers</span><span class="p">)</span>
<span class="k">print</span> <span class="n">sig</span><span class="p">,</span> <span class="n">email</span>
</pre></div>

<p>Output:</p>
<pre><code>DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple;
 d=topdog-software.com; i=@topdog-software.com; q=dns/txt; s=default;
 t=1336488625; h=From : To : Subject;
 bh=skd2vA1wrCEzamCzKOvVKCaVhhpP1ihoQgGldgTSVUE=; b=vGQgSjJxkTZe+NZZl
lqszgxGshTcixlcfFos+XpLnAj1fnhA5SuBASoB4dVQUlVW76U5s9Dn1zSSsKH
6bCahl4oPqZaE5t6Ke5wpGwA+cBWZRrSuDDD/L8g9nYi04SVb+lMF9mJyQCeZj
pBtMomaOvGF8GNXsiKTFZR9RDv0wWw=
From: Sender &lt;sender@topdog-software.com&gt;
To: Recipient &lt;recipient@example.com&gt;
Subject: Test message

Hi There,

This is a simple message that will be signed by pydkim

--The signer
</code></pre>
<p>Verify a message (I use the same message signed above)</p>
<div class="pygments_murphy"><pre><span class="kn">from</span> <span class="nn">dkim</span> <span class="kn">import</span> <span class="n">verify</span>

<span class="k">if</span> <span class="n">verify</span><span class="p">(</span><span class="nb">open</span><span class="p">(</span><span class="s">&#39;email.txt&#39;</span><span class="p">)</span><span class="o">.</span><span class="n">read</span><span class="p">()):</span>
    <span class="k">print</span> <span class="s">&quot;Email verified successfully&quot;</span>
</pre></div>

<pre><code>True
</code></pre>
<h3>Command line</h3>
<p>Sign a message</p>
<pre><code>dkimsign.py selector domain privatekeyfile [identity]
</code></pre>
<p>Verify a message</p>
<pre><code>cat email.txt | dkimverify.py
echo $?
</code></pre>
<h2>And there is more.</h2>
<p>For details of the API please refer to the <a href="http://hewgill.com/pydkim/html/">documentation</a>.
Happy DKIMing</p>]]></content:encoded>
    </item>
    <item>
      <title>Python modules you should know: dnspython</title>
      <link>http://www.topdog.za.net/2012/05/07/python-modules-you-should-know:-dnspython</link>
      <pubDate>Mon, 07 May 2012 16:40:00 SAST</pubDate>
      <category><![CDATA[Python]]></category>
      <category><![CDATA[PyMYSK]]></category>
      <category><![CDATA[Howto]]></category>
      <guid isPermaLink="true">http://www.topdog.za.net/2012/05/07/python-modules-you-should-know:-dnspython</guid>
      <description>Python modules you should know: dnspython</description>
      <content:encoded><![CDATA[<p>Next in our series of <a href="http://www.topdog.za.net/category/pymysk/"><em>Python modules you should know</em></a>
is dnspython. This package is a DNS toolkit, you can use it to perform
DNS queries, Zone transfers and Dynamic Updates in Python programs.</p>
<h2>Home page</h2>
<ul>
<li><a href="http://www.dnspython.org/">http://www.dnspython.org/</a></li>
</ul>
<h2>Use</h2>
<p>dnspython is a DNS toolkit for Python. It supports almost all record types.
It can be used for queries, zone transfers, and dynamic updates. It supports
TSIG authenticated messages and EDNS0.</p>
<p>dnspython provides both high and low level access to DNS. The high level
classes perform queries for data of a given name, type, and class, and
return an answer set. The low level classes allow direct manipulation of
DNS zones, messages, names, and records.</p>
<h2>Installation</h2>
<pre><code>pip install dnspython
</code></pre>
<h2>Usage</h2>
<p>Lookup DNS records (A, AAAA, MX, NS)</p>
<p><strong>A Records</strong></p>
<div class="pygments_murphy"><pre><span class="kn">import</span> <span class="nn">dns.resolver</span>
<span class="n">answers</span> <span class="o">=</span> <span class="n">dns</span><span class="o">.</span><span class="n">resolver</span><span class="o">.</span><span class="n">query</span><span class="p">(</span><span class="s">&#39;topdog.za.net&#39;</span><span class="p">,</span> <span class="s">&#39;A&#39;</span><span class="p">)</span>
<span class="k">for</span> <span class="n">rdata</span> <span class="ow">in</span> <span class="n">answers</span><span class="p">:</span>
    <span class="k">print</span> <span class="n">rdata</span><span class="o">.</span><span class="n">address</span>
</pre></div>

<p><strong>AAAA Records</strong></p>
<div class="pygments_murphy"><pre><span class="kn">import</span> <span class="nn">dns.resolver</span>
<span class="n">answers</span> <span class="o">=</span> <span class="n">dns</span><span class="o">.</span><span class="n">resolver</span><span class="o">.</span><span class="n">query</span><span class="p">(</span><span class="s">&#39;topdog.za.net&#39;</span><span class="p">,</span> <span class="s">&#39;AAAA&#39;</span><span class="p">)</span>
<span class="k">for</span> <span class="n">rdata</span> <span class="ow">in</span> <span class="n">answers</span><span class="p">:</span>
    <span class="k">print</span> <span class="n">rdata</span><span class="o">.</span><span class="n">address</span>
</pre></div>

<p><strong>MX Records</strong></p>
<div class="pygments_murphy"><pre><span class="kn">import</span> <span class="nn">dns.resolver</span>
<span class="n">answers</span> <span class="o">=</span> <span class="n">dns</span><span class="o">.</span><span class="n">resolver</span><span class="o">.</span><span class="n">query</span><span class="p">(</span><span class="s">&#39;topdog.za.net&#39;</span><span class="p">,</span> <span class="s">&#39;MX&#39;</span><span class="p">)</span>
<span class="k">for</span> <span class="n">rdata</span> <span class="ow">in</span> <span class="n">answers</span><span class="p">:</span>
    <span class="k">print</span> <span class="s">&#39;host&#39;</span><span class="p">,</span> <span class="n">rdata</span><span class="o">.</span><span class="n">exchange</span><span class="p">,</span> <span class="s">&#39;has preference&#39;</span><span class="p">,</span> <span class="n">rdata</span><span class="o">.</span><span class="n">preference</span>
</pre></div>

<p><strong>NS Records</strong></p>
<div class="pygments_murphy"><pre><span class="kn">import</span> <span class="nn">dns.resolver</span>
<span class="n">answers</span> <span class="o">=</span> <span class="n">dns</span><span class="o">.</span><span class="n">resolver</span><span class="o">.</span><span class="n">query</span><span class="p">(</span><span class="s">&#39;topdog.za.net&#39;</span><span class="p">,</span> <span class="s">&#39;NS&#39;</span><span class="p">)</span>
<span class="k">for</span> <span class="n">rdata</span> <span class="ow">in</span> <span class="n">answers</span><span class="p">:</span>
    <span class="k">print</span> <span class="n">rdata</span><span class="o">.</span><span class="n">to_text</span><span class="p">()</span>
</pre></div>

<p>Transfer a Zone from a server.</p>
<div class="pygments_murphy"><pre><span class="kn">import</span> <span class="nn">dns.zone</span>
<span class="kn">import</span> <span class="nn">dns.query</span>
<span class="n">zone</span> <span class="o">=</span> <span class="n">dns</span><span class="o">.</span><span class="n">zone</span><span class="o">.</span><span class="n">from_xfr</span><span class="p">(</span><span class="n">dns</span><span class="o">.</span><span class="n">query</span><span class="o">.</span><span class="n">xfr</span><span class="p">(</span><span class="s">&#39;174.136.108.83&#39;</span><span class="p">,</span> <span class="s">&#39;topdog.za.net&#39;</span><span class="p">))</span>
<span class="k">print</span> <span class="s">&quot;*&quot;</span> <span class="o">*</span> <span class="mi">10</span><span class="p">,</span> <span class="s">&quot;A records&quot;</span><span class="p">,</span> <span class="s">&quot;*&quot;</span> <span class="o">*</span> <span class="mi">10</span>
<span class="k">for</span> <span class="p">(</span><span class="n">name</span><span class="p">,</span> <span class="n">ttl</span><span class="p">,</span> <span class="n">rdata</span><span class="p">)</span> <span class="ow">in</span> <span class="n">zone</span><span class="o">.</span><span class="n">iterate_rdatas</span><span class="p">(</span><span class="s">&#39;A&#39;</span><span class="p">):</span>
    <span class="k">print</span> <span class="n">name</span><span class="p">,</span> <span class="s">&quot;with TTL&quot;</span><span class="p">,</span> <span class="n">ttl</span><span class="p">,</span> <span class="s">&quot;points to&quot;</span><span class="p">,</span> <span class="n">rdata</span>
<span class="k">print</span> <span class="s">&quot;*&quot;</span> <span class="o">*</span> <span class="mi">10</span><span class="p">,</span> <span class="s">&quot;MX records&quot;</span><span class="p">,</span> <span class="s">&quot;*&quot;</span> <span class="o">*</span> <span class="mi">10</span>
<span class="k">for</span> <span class="p">(</span><span class="n">name</span><span class="p">,</span> <span class="n">ttl</span><span class="p">,</span> <span class="n">rdata</span><span class="p">)</span> <span class="ow">in</span> <span class="n">zone</span><span class="o">.</span><span class="n">iterate_rdatas</span><span class="p">(</span><span class="s">&#39;MX&#39;</span><span class="p">):</span>
    <span class="k">print</span> <span class="n">name</span><span class="p">,</span> <span class="s">&quot;with TTL&quot;</span><span class="p">,</span> <span class="n">ttl</span><span class="p">,</span> <span class="s">&quot;points to&quot;</span><span class="p">,</span> <span class="n">rdata</span>
<span class="k">print</span> <span class="s">&quot;*&quot;</span> <span class="o">*</span> <span class="mi">10</span><span class="p">,</span> <span class="s">&quot;NS records&quot;</span><span class="p">,</span> <span class="s">&quot;*&quot;</span> <span class="o">*</span> <span class="mi">10</span>
<span class="k">for</span> <span class="p">(</span><span class="n">name</span><span class="p">,</span> <span class="n">ttl</span><span class="p">,</span> <span class="n">rdata</span><span class="p">)</span> <span class="ow">in</span> <span class="n">zone</span><span class="o">.</span><span class="n">iterate_rdatas</span><span class="p">(</span><span class="s">&#39;NS&#39;</span><span class="p">):</span>
    <span class="k">print</span> <span class="n">name</span><span class="p">,</span> <span class="s">&quot;with TTL&quot;</span><span class="p">,</span> <span class="n">ttl</span><span class="p">,</span> <span class="s">&quot;points to&quot;</span><span class="p">,</span> <span class="n">rdata</span>
</pre></div>

<p>Generate reverse names</p>
<div class="pygments_murphy"><pre><span class="kn">import</span> <span class="nn">dns.reversename</span>
<span class="k">print</span> <span class="n">dns</span><span class="o">.</span><span class="n">reversename</span><span class="o">.</span><span class="n">from_address</span><span class="p">(</span><span class="s">&#39;174.136.108.83&#39;</span><span class="p">)</span>
</pre></div>

<p>Perform a Dynamic record update (example from documentation modified)</p>
<div class="pygments_murphy"><pre><span class="kn">import</span> <span class="nn">dns.query</span>
<span class="kn">import</span> <span class="nn">dns.tsigkeyring</span>
<span class="kn">import</span> <span class="nn">dns.update</span>
<span class="kn">import</span> <span class="nn">sys</span>

<span class="k">if</span> <span class="n">__name__</span> <span class="o">==</span> <span class="s">&#39;__main__&#39;</span><span class="p">:</span>
    <span class="n">keyring</span> <span class="o">=</span> <span class="n">dns</span><span class="o">.</span><span class="n">tsigkeyring</span><span class="o">.</span><span class="n">from_text</span><span class="p">({</span>
        <span class="s">&#39;host-example.&#39;</span> <span class="p">:</span> <span class="s">&#39;XXXXXXXXXXXXXXXXXXXXXX==&#39;</span>
    <span class="p">})</span>
    <span class="c"># Replace an A record</span>
    <span class="n">update</span> <span class="o">=</span> <span class="n">dns</span><span class="o">.</span><span class="n">update</span><span class="o">.</span><span class="n">Update</span><span class="p">(</span><span class="s">&#39;example.com&#39;</span><span class="p">,</span> <span class="n">keyring</span><span class="o">=</span><span class="n">keyring</span><span class="p">)</span>
    <span class="n">update</span><span class="o">.</span><span class="n">replace</span><span class="p">(</span><span class="s">&#39;host&#39;</span><span class="p">,</span> <span class="mi">300</span><span class="p">,</span> <span class="s">&#39;a&#39;</span><span class="p">,</span> <span class="n">sys</span><span class="o">.</span><span class="n">argv</span><span class="p">[</span><span class="mi">1</span><span class="p">])</span>
    <span class="n">response</span> <span class="o">=</span> <span class="n">dns</span><span class="o">.</span><span class="n">query</span><span class="o">.</span><span class="n">tcp</span><span class="p">(</span><span class="n">update</span><span class="p">,</span> <span class="s">&#39;10.0.0.1&#39;</span><span class="p">)</span>
</pre></div>

<h2>And there is more</h2>
<p>There is more that can be done using this package please refer to
the <a href="http://www.dnspython.org/docs/1.10.0/html/">documentation</a>.</p>]]></content:encoded>
    </item>
    <item>
      <title>Python modules you should know: IPy</title>
      <link>http://www.topdog.za.net/2012/05/06/python-modules-you-should-know:-ipy</link>
      <pubDate>Sun, 06 May 2012 16:40:00 SAST</pubDate>
      <category><![CDATA[Python]]></category>
      <category><![CDATA[PyMYSK]]></category>
      <category><![CDATA[Howto]]></category>
      <guid isPermaLink="true">http://www.topdog.za.net/2012/05/06/python-modules-you-should-know:-ipy</guid>
      <description>Python modules you should know: IPy</description>
      <content:encoded><![CDATA[<p>Next in our series of <a href="http://www.topdog.za.net/category/pymysk/"><em>Python modules you should know</em></a>
is IPy. This package is used to manipulate IPv4 and IPv6 addresses in Python programs.</p>
<h2>Home page</h2>
<ul>
<li><a href="https://github.com/haypo/python-ipy/">https://github.com/haypo/python-ipy/</a></li>
</ul>
<h2>Use</h2>
<p>The IP class allows a comfortable parsing and handling for most
notations in use for IPv4 and IPv6 addresses and networks. It was
greatly inspired by RIPE's Perl module NET::IP's interface but
doesn't share the implementation.</p>
<h2>Installation</h2>
<pre><code>pip install IPy
</code></pre>
<h2>Usage</h2>
<p>Print IP addresses in an IP range</p>
<div class="pygments_murphy"><pre><span class="kn">from</span> <span class="nn">IPy</span> <span class="kn">import</span> <span class="n">IP</span>
<span class="n">network</span> <span class="o">=</span> <span class="n">IP</span><span class="p">(</span><span class="s">&#39;192.168.0.0/30&#39;</span><span class="p">)</span>
<span class="k">for</span> <span class="n">ip</span> <span class="ow">in</span> <span class="n">network</span><span class="p">:</span>
    <span class="k">print</span> <span class="n">ip</span>
</pre></div>

<p>Output:</p>
<pre><code>192.168.0.0
192.168.0.1
192.168.0.2
192.168.0.3
</code></pre>
<p>Generate Reverse names for reverse lookup/PTR records</p>
<div class="pygments_murphy"><pre><span class="kn">from</span> <span class="nn">IPy</span> <span class="kn">import</span> <span class="n">IP</span>
<span class="n">network</span> <span class="o">=</span> <span class="n">IP</span><span class="p">(</span><span class="s">&#39;192.168.0.0/30&#39;</span><span class="p">)</span>
<span class="k">for</span> <span class="n">ip</span> <span class="ow">in</span> <span class="n">network</span><span class="p">:</span>
    <span class="k">print</span> <span class="n">ip</span><span class="o">.</span><span class="n">reverseName</span><span class="p">()</span>
</pre></div>

<div class="pygments_murphy"><pre><span class="kn">from</span> <span class="nn">IPy</span> <span class="kn">import</span> <span class="n">IP</span>
<span class="n">network</span> <span class="o">=</span> <span class="n">IP</span><span class="p">(</span><span class="s">&#39;192.168.0.0/30&#39;</span><span class="p">)</span><span class="o">.</span><span class="n">reverseNames</span><span class="p">()</span>
<span class="k">for</span> <span class="n">ip</span> <span class="ow">in</span> <span class="n">network</span><span class="p">:</span>
    <span class="k">print</span> <span class="n">ip</span>
</pre></div>

<p>Output:</p>
<pre><code>0.0.168.192.in-addr.arpa.
1.0.168.192.in-addr.arpa.
2.0.168.192.in-addr.arpa.
3.0.168.192.in-addr.arpa.
</code></pre>
<p>Check IP version:</p>
<div class="pygments_murphy"><pre><span class="kn">from</span> <span class="nn">IPy</span> <span class="kn">import</span> <span class="n">IP</span>
<span class="k">print</span> <span class="n">IP</span><span class="p">(</span><span class="s">&#39;192.168.0.0/30&#39;</span><span class="p">)</span><span class="o">.</span><span class="n">version</span><span class="p">()</span>
<span class="k">print</span> <span class="n">IP</span><span class="p">(</span><span class="s">&#39;::1&#39;</span><span class="p">)</span><span class="o">.</span><span class="n">version</span><span class="p">()</span>
</pre></div>

<p>Output:</p>
<pre><code>4
6
</code></pre>
<p>Get network prefixes</p>
<div class="pygments_murphy"><pre><span class="kn">from</span> <span class="nn">IPy</span> <span class="kn">import</span> <span class="n">IP</span>
<span class="k">print</span> <span class="n">IP</span><span class="p">(</span><span class="s">&#39;192.168.0.0/30&#39;</span><span class="p">)</span>
<span class="k">print</span> <span class="n">IP</span><span class="p">(</span><span class="s">&#39;192.168.0.0/255.255.255.252&#39;</span><span class="p">)</span>
<span class="k">print</span> <span class="n">IP</span><span class="p">(</span><span class="s">&#39;192.168.0.0-192.168.0.3)</span>
</pre></div>

<p>Output:</p>
<pre><code>192.168.0.0/30
192.168.0.0/30
192.168.0.0/30
</code></pre>
<p>Get the broadcast address</p>
<div class="pygments_murphy"><pre><span class="kn">from</span> <span class="nn">IPy</span> <span class="kn">import</span> <span class="n">IP</span>
<span class="k">print</span> <span class="n">IP</span><span class="p">(</span><span class="s">&#39;192.168.0.0/30&#39;</span><span class="p">)</span><span class="o">.</span><span class="n">broadcast</span><span class="p">()</span>
</pre></div>

<p>Output:</p>
<pre><code>192.168.0.3
</code></pre>
<p>Get the network mask</p>
<div class="pygments_murphy"><pre><span class="kn">from</span> <span class="nn">IPy</span> <span class="kn">import</span> <span class="n">IP</span>
<span class="k">print</span> <span class="n">IP</span><span class="p">(</span><span class="s">&#39;192.168.0.0/30&#39;</span><span class="p">)</span><span class="o">.</span><span class="n">netmask</span><span class="p">()</span>
</pre></div>

<p>Output:</p>
<pre><code>255.255.255.252
</code></pre>
<p>Check if an IP address is within a network</p>
<div class="pygments_murphy"><pre><span class="kn">from</span> <span class="nn">IPy</span> <span class="kn">import</span> <span class="n">IP</span>
<span class="s">&#39;192.168.0.1&#39;</span> <span class="ow">in</span> <span class="n">IP</span><span class="p">(</span><span class="s">&#39;192.168.0.0/30&#39;</span><span class="p">)</span>
</pre></div>

<p>Check a network type LOOPBACK, PRIVATE, PUBLIC, RESERVED</p>
<div class="pygments_murphy"><pre><span class="kn">from</span> <span class="nn">IPy</span> <span class="kn">import</span> <span class="n">IP</span>
<span class="k">print</span> <span class="n">IP</span><span class="p">(</span><span class="s">&#39;192.168.0.1&#39;</span><span class="p">)</span><span class="o">.</span><span class="n">iptype</span><span class="p">()</span>
</pre></div>

<p>Output:</p>
<pre><code>PRIVATE
</code></pre>
<h2>And there is more</h2>
<p>There is more that can be done using this package please refer to
the documentation or run.</p>
<div class="pygments_murphy"><pre><span class="kn">import</span> <span class="nn">IPy</span>
<span class="n">help</span><span class="p">(</span><span class="n">IPy</span><span class="p">)</span>
</pre></div>]]></content:encoded>
    </item>
    <item>
      <title>Python modules you should know: PyClamd</title>
      <link>http://www.topdog.za.net/2012/05/02/python-modules-you-should-know:-pyclamd</link>
      <pubDate>Wed, 02 May 2012 12:39:00 SAST</pubDate>
      <category><![CDATA[Python]]></category>
      <category><![CDATA[PyMYSK]]></category>
      <category><![CDATA[Howto]]></category>
      <guid isPermaLink="true">http://www.topdog.za.net/2012/05/02/python-modules-you-should-know:-pyclamd</guid>
      <description>Python modules you should know: PyClamd</description>
      <content:encoded><![CDATA[<p>Next in our series of <a href="http://www.topdog.za.net/category/pymysk/"><em>Python modules you should know</em></a>
is PyClamd. This package is used integrate Clamav Virus detection in Python programs.</p>
<h2>Home page</h2>
<ul>
<li><a href="http://xael.org/norman/python/pyclamd/">http://xael.org/norman/python/pyclamd/</a></li>
</ul>
<h2>Use</h2>
<p>pyClamd is a python interface to Clamd (Clamav daemon). By using pyClamd, you can add
virus detection capabilities to your python software in an efficient and easy way.</p>
<p>pyClamd may be used by a closed source product, as it does not link with the GPL licensed
libclamav.</p>
<h2>Installation</h2>
<p>This package is not available on the cheeseshop (PYPI) so you need to install it by
downloading the module.</p>
<pre><code>wget http://xael.org/norman/python/pyclamd/pyclamd.py
mv pyclamd.py $(python -c "from distutils.sysconfig import get_python_lib; print get_python_lib()")/
</code></pre>
<h2>Usage</h2>
<p>pyClamd supports connections to clamd using both TCP and UNIX sockets.</p>
<p><strong>TCP</strong></p>
<div class="pygments_murphy"><pre><span class="kn">import</span> <span class="nn">pyclamd</span>
<span class="n">pyclamd</span><span class="o">.</span><span class="n">init_network_socket</span><span class="p">(</span><span class="s">&#39;localhost&#39;</span><span class="p">,</span> <span class="mi">3310</span><span class="p">)</span>
<span class="k">print</span> <span class="n">pyclamd</span><span class="o">.</span><span class="n">version</span><span class="p">()</span>
</pre></div>

<p>Output:</p>
<pre><code>ClamAV 0.97.4/14869/Tue May  1 22:38:26 2012
</code></pre>
<p><strong>Unix socket</strong></p>
<div class="pygments_murphy"><pre><span class="kn">import</span> <span class="nn">pyclamd</span>
<span class="n">pyclamd</span><span class="o">.</span><span class="n">init_unix_socket</span><span class="p">(</span><span class="s">&#39;/tmp/clamd.socket&#39;</span><span class="p">)</span>
<span class="k">print</span> <span class="n">pyclamd</span><span class="o">.</span><span class="n">version</span><span class="p">()</span>
</pre></div>

<p>Output:</p>
<pre><code>ClamAV 0.97.4/14869/Tue May  1 22:38:26 2012
</code></pre>
<p><strong>Scan files</strong></p>
<div class="pygments_murphy"><pre><span class="kn">import</span> <span class="nn">pyclamd</span>
<span class="n">pyclamd</span><span class="o">.</span><span class="n">init_unix_socket</span><span class="p">(</span><span class="s">&#39;/tmp/clamd.socket&#39;</span><span class="p">)</span>
<span class="n">pyclamd</span><span class="o">.</span><span class="n">contscan_file</span><span class="p">(</span><span class="s">&#39;/tmp&#39;</span><span class="p">)</span>
</pre></div>

<p><strong>Scan and stop if virus detected</strong></p>
<div class="pygments_murphy"><pre><span class="kn">import</span> <span class="nn">pyclamd</span>
<span class="n">pyclamd</span><span class="o">.</span><span class="n">init_unix_socket</span><span class="p">(</span><span class="s">&#39;/tmp/clamd.socket&#39;</span><span class="p">)</span>
<span class="n">pyclamd</span><span class="o">.</span><span class="n">scan_file</span><span class="p">(</span><span class="s">&#39;/tmp&#39;</span><span class="p">)</span>
</pre></div>

<p><strong>Ping server to check if still alive</strong></p>
<div class="pygments_murphy"><pre><span class="kn">import</span> <span class="nn">pyclamd</span>
<span class="n">pyclamd</span><span class="o">.</span><span class="n">init_unix_socket</span><span class="p">(</span><span class="s">&#39;/tmp/clamd.socket&#39;</span><span class="p">)</span>
<span class="n">pyclamd</span><span class="o">.</span><span class="n">ping</span><span class="p">()</span>
</pre></div>

<p><strong>Scan a stream</strong></p>
<div class="pygments_murphy"><pre><span class="kn">import</span> <span class="nn">pyclamd</span>
<span class="n">pyclamd</span><span class="o">.</span><span class="n">init_unix_socket</span><span class="p">(</span><span class="s">&#39;/tmp/clamd.socket&#39;</span><span class="p">)</span>
<span class="n">mystring</span> <span class="o">=</span> <span class="s">&#39;X5O!P%@AP[4\PZX54(P^)7CC)7}$EICAR-STANDARD-ANTIVIRUS-TEST-FILE!$H+H*&#39;</span>
<span class="n">pyclamd</span><span class="o">.</span><span class="n">scan_stream</span><span class="p">(</span><span class="n">mystring</span><span class="p">)</span>
</pre></div>

<p>Output:</p>
<pre><code>{'stream': 'Eicar-Test-Signature'}
</code></pre>
<p><strong>Reload clamd</strong></p>
<div class="pygments_murphy"><pre><span class="kn">import</span> <span class="nn">pyclamd</span>
<span class="n">pyclamd</span><span class="o">.</span><span class="n">init_unix_socket</span><span class="p">(</span><span class="s">&#39;/tmp/clamd.socket&#39;</span><span class="p">)</span>
<span class="n">pyclamd</span><span class="o">.</span><span class="n">reload</span><span class="p">()</span>
</pre></div>

<p>Output:</p>
<pre><code>'RELOADING'
</code></pre>
<p><strong>Shutdown clamd</strong></p>
<div class="pygments_murphy"><pre><span class="kn">import</span> <span class="nn">pyclamd</span>
<span class="n">pyclamd</span><span class="o">.</span><span class="n">init_unix_socket</span><span class="p">(</span><span class="s">&#39;/tmp/clamd.socket&#39;</span><span class="p">)</span>
<span class="n">pyclamd</span><span class="o">.</span><span class="n">shutdown</span><span class="p">()</span>
</pre></div>

<p>The module raises various exceptions that you will need to catch, please refer to the
<a href="http://xael.org/norman/python/pyclamd/">documentation</a> for details.</p>]]></content:encoded>
    </item>
    <item>
      <title>Python modules you should know: Pwtools</title>
      <link>http://www.topdog.za.net/2012/05/01/python-modules-you-should-know:-pwtools</link>
      <pubDate>Tue, 01 May 2012 12:39:00 SAST</pubDate>
      <category><![CDATA[Python]]></category>
      <category><![CDATA[PyMYSK]]></category>
      <category><![CDATA[Howto]]></category>
      <guid isPermaLink="true">http://www.topdog.za.net/2012/05/01/python-modules-you-should-know:-pwtools</guid>
      <description>Python modules you should know: Pwtools</description>
      <content:encoded><![CDATA[<p>Next in our series of <a href="http://www.topdog.za.net/category/pymysk/"><em>Python modules you should know</em></a>
is Pwtools. This package is used to generate and test passwords in Python programs.</p>
<h2>Home page</h2>
<ul>
<li><a href="http://alastairs-place.net/projects/pwtools/">http://alastairs-place.net/projects/pwtools/</a></li>
</ul>
<h2>Use</h2>
<p>pwtools is a Python package that provides the ability to generate passwords, and
also allows you to test them to ensure that they are reasonably secure.</p>
<p>The algorithms used were borrowed from the <a href="http://www.openwall.com/">Openwall</a> Project’s
<a href="http://www.openwall.com/passwdqc">passwdqc</a> project, but have been re-implemented in Python
for increased portability.</p>
<h2>Installation</h2>
<p>This package is not available on the cheeseshop (PYPI) so you need to install it from the
Mercurial repository.</p>
<pre><code>pip install hg+http://alastairs-place.net/hg/pwtools
</code></pre>
<h2>Usage</h2>
<p>Generate a strong password:</p>
<div class="pygments_murphy"><pre><span class="kn">from</span> <span class="nn">pwtools</span> <span class="kn">import</span> <span class="n">PasswordGenerator</span>
<span class="n">pwgen</span> <span class="o">=</span> <span class="n">PasswordGenerator</span><span class="p">()</span>
<span class="n">pwgen</span><span class="o">.</span><span class="n">generate</span><span class="p">()</span>
</pre></div>

<p>Output:</p>
<pre><code>'amaze*Period&amp;Thirst'
</code></pre>
<p>Check password strength:</p>
<div class="pygments_murphy"><pre><span class="kn">from</span> <span class="nn">pwtools</span> <span class="kn">import</span> <span class="n">PasswordChecker</span>
<span class="n">pwchecker</span> <span class="o">=</span> <span class="n">PasswordChecker</span><span class="p">(</span><span class="s">&#39;/usr/share/dict/words&#39;</span><span class="p">)</span>
<span class="n">pwchecker</span><span class="o">.</span><span class="n">checkPassword</span><span class="p">(</span><span class="s">&#39;password&#39;</span><span class="p">)</span>
<span class="n">pwchecker</span><span class="o">.</span><span class="n">checkPassword</span><span class="p">(</span><span class="s">&#39;zxcvbnm&#39;</span><span class="p">)</span>
<span class="n">pwchecker</span><span class="o">.</span><span class="n">checkPassword</span><span class="p">(</span><span class="s">&#39;123456abcdef&#39;</span><span class="p">)</span>
<span class="n">pwchecker</span><span class="o">.</span><span class="n">checkPassword</span><span class="p">(</span><span class="s">&#39;m1ll10n&#39;</span><span class="p">)</span>
<span class="n">pwchecker</span><span class="o">.</span><span class="n">checkPassword</span><span class="p">(</span><span class="s">&#39;amaze*Period&amp;Thirst&#39;</span><span class="p">)</span>
</pre></div>

<p>Output:</p>
<pre><code>'too simple (not enough different kinds of character)'
'too simple (not enough different kinds of character)'
'based on a common sequence of characters'
'too simple (not enough different kinds of character)'
False
</code></pre>]]></content:encoded>
    </item>
    <item>
      <title>Python modules you should know: SlimIt</title>
      <link>http://www.topdog.za.net/2012/04/30/python-modules-you-should-know:-slimit</link>
      <pubDate>Mon, 30 Apr 2012 07:10:00 SAST</pubDate>
      <category><![CDATA[Python]]></category>
      <category><![CDATA[PyMYSK]]></category>
      <category><![CDATA[Howto]]></category>
      <guid isPermaLink="true">http://www.topdog.za.net/2012/04/30/python-modules-you-should-know:-slimit</guid>
      <description>Python modules you should know: SlimIt</description>
      <content:encoded><![CDATA[<p>Next in our series of <a href="http://www.topdog.za.net/category/pymysk/"><em>Python modules you should know</em></a>
is SlimIt. I previously <a href="http://www.topdog.za.net/2012/04/29/python-modules-you-should-know:-cssmin/">wrote</a>
about the minification of CSS files, the Slimit package is used for minification of Javascript files.</p>
<h2>Home page</h2>
<ul>
<li><a href="http://slimit.org/">http://slimit.org/</a></li>
</ul>
<h2>Use</h2>
<p>SlimIt is a JavaScript minifier written in Python. It compiles JavaScript into more compact
code so that it downloads and runs faster.</p>
<p>SlimIt also provides a library that includes a JavaScript parser, lexer, pretty printer and
a tree visitor.</p>
<h2>Installation</h2>
<pre><code>pip install slimit
</code></pre>
<h2>Usage</h2>
<p>The package provides a command line interface as well as Python functions.</p>
<h3>Python functions</h3>
<h4>Minify Javascript</h4>
<div class="pygments_murphy"><pre><span class="kn">from</span> <span class="nn">slimit</span> <span class="kn">import</span> <span class="n">minify</span>
<span class="n">minified</span> <span class="o">=</span> <span class="n">minify</span><span class="p">(</span><span class="nb">open</span><span class="p">(</span><span class="s">&#39;jquery-1.7.2.js&#39;</span><span class="p">)</span><span class="o">.</span><span class="n">read</span><span class="p">(),</span> <span class="n">mangle</span><span class="o">=</span><span class="bp">True</span><span class="p">,</span> <span class="n">mangle_toplevel</span><span class="o">=</span><span class="bp">True</span><span class="p">)</span>
<span class="k">print</span> <span class="n">minified</span>
</pre></div>

<h4>Modify Javascript within Python and beautify it</h4>
<p>This example is taken directly from the documentation. It modifies the counter variable
changing it from <strong>"i"</strong> to <strong>"hello"</strong> and formats it in a more readable style.</p>
<div class="pygments_murphy"><pre><span class="kn">from</span> <span class="nn">slimit.parser</span> <span class="kn">import</span> <span class="n">Parser</span>
<span class="kn">from</span> <span class="nn">slimit.visitors</span> <span class="kn">import</span> <span class="n">nodevisitor</span>
<span class="kn">from</span> <span class="nn">slimit</span> <span class="kn">import</span> <span class="n">ast</span>

<span class="n">parser</span> <span class="o">=</span> <span class="n">Parser</span><span class="p">()</span>
<span class="n">tree</span> <span class="o">=</span> <span class="n">parser</span><span class="o">.</span><span class="n">parse</span><span class="p">(</span><span class="s">&#39;for(var i=0; i&lt;10; i++) {var x=5+i;}&#39;</span><span class="p">)</span>
<span class="k">for</span> <span class="n">node</span> <span class="ow">in</span> <span class="n">nodevisitor</span><span class="o">.</span><span class="n">visit</span><span class="p">(</span><span class="n">tree</span><span class="p">):</span>
    <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">node</span><span class="p">,</span> <span class="n">ast</span><span class="o">.</span><span class="n">Identifier</span><span class="p">)</span> <span class="ow">and</span> <span class="n">node</span><span class="o">.</span><span class="n">value</span> <span class="o">==</span> <span class="s">&#39;i&#39;</span><span class="p">:</span>
        <span class="n">node</span><span class="o">.</span><span class="n">value</span> <span class="o">=</span> <span class="s">&#39;hello&#39;</span>
<span class="k">print</span> <span class="n">tree</span><span class="o">.</span><span class="n">to_ecma</span><span class="p">()</span>
</pre></div>

<p>Output:</p>
<pre><code>for (var hello = 0; hello &lt; 10; hello++) {
  var x = 5 + hello;
}
</code></pre>
<h3>Command line</h3>
<pre><code>slimit --mangle &lt; jquery-1.7.2.js &gt; jquery-1.7.2.slimit.default.js
</code></pre>
<h4>Performance</h4>
<p>The performance is very good, most times it creates smaller files than the <a href="http://developer.yahoo.com/yui/compressor/">YUI compresser</a>.
I tested minifying Jquery using 3 javascript minification tools:</p>
<ul>
<li>jsmin</li>
<li>yuicompressor</li>
<li>slimit</li>
</ul>
<p>The results are below.</p>
<pre><code>-rw-r--r--  1 andrew  staff   247K Mar 21 21:46 jquery-1.7.2.js
-rw-r--r--  1 andrew  staff   138K Apr 30 08:26 jquery-1.7.2.jsmin.js
-rw-r--r--  1 andrew  staff    96K Apr 30 08:22 jquery-1.7.2.slimit.js
-rw-r--r--  1 andrew  staff   103K Apr 30 08:19 jquery-1.7.2.yui.js
</code></pre>
<h2>And there is more</h2>
<p>Slimit also exposes JavaScript <a href="https://en.wikipedia.org/wiki/Parser">parser</a> and
<a href="https://en.wikipedia.org/wiki/Lexical_analysis">lexer</a> functions which you can use within your code,
please refer to the <a href="http://slimit.readthedocs.org/en/latest/index.html#using-lexer-in-your-project">documentation</a> for usage information.</p>]]></content:encoded>
    </item>
    <item>
      <title>Python modules you should know: cssmin</title>
      <link>http://www.topdog.za.net/2012/04/29/python-modules-you-should-know:-cssmin</link>
      <pubDate>Sun, 29 Apr 2012 14:10:00 SAST</pubDate>
      <category><![CDATA[Python]]></category>
      <category><![CDATA[PyMYSK]]></category>
      <category><![CDATA[Howto]]></category>
      <guid isPermaLink="true">http://www.topdog.za.net/2012/04/29/python-modules-you-should-know:-cssmin</guid>
      <description>Python modules you should know: cssmin</description>
      <content:encoded><![CDATA[<p>Next in our series of <a href="http://www.topdog.za.net/category/pymysk/"><em>Python modules you should know</em></a>
is cssmin. <a href="https://en.wikipedia.org/wiki/Minification_%28programming%29">Minification</a> has recently
gained prominence in the web 2.0 world due to the need to optimize web application performance.</p>
<p>The cssmin package is used to minify css files.</p>
<h2>Home page</h2>
<ul>
<li><a href="https://github.com/zacharyvoase/cssmin">https://github.com/zacharyvoase/cssmin</a></li>
</ul>
<h2>Use</h2>
<p>cssmin is a Python port of the <a href="http://developer.yahoo.com/yui/compressor/">YUI CSS Compressor</a>.
It is used to minify css files, which helps improve web application performance by reducing page
load times.</p>
<h2>Installation</h2>
<pre><code>pip install cssmin
</code></pre>
<h2>Usage</h2>
<p>The package provides a command line interface as well as Python functions.</p>
<h3>Python function</h3>
<div class="pygments_murphy"><pre><span class="kn">import</span> <span class="nn">cssmin</span>
<span class="n">minified</span> <span class="o">=</span> <span class="n">cssmin</span><span class="o">.</span><span class="n">cssmin</span><span class="p">(</span><span class="nb">open</span><span class="p">(</span><span class="s">&#39;style.css&#39;</span><span class="p">)</span><span class="o">.</span><span class="n">read</span><span class="p">())</span>
<span class="k">print</span> <span class="n">minified</span>
</pre></div>

<h3>Commandline</h3>
<pre><code>cssmin --wrap 1000 &lt; style.css &gt; style.min.css
</code></pre>
<p>Thats it, nice and sweet.</p>]]></content:encoded>
    </item>
    <item>
      <title>Python modules you should know: bcrypt</title>
      <link>http://www.topdog.za.net/2012/04/28/python-modules-you-should-know:-bcrypt</link>
      <pubDate>Sat, 28 Apr 2012 08:05:00 SAST</pubDate>
      <category><![CDATA[Python]]></category>
      <category><![CDATA[PyMYSK]]></category>
      <category><![CDATA[Howto]]></category>
      <guid isPermaLink="true">http://www.topdog.za.net/2012/04/28/python-modules-you-should-know:-bcrypt</guid>
      <description>Python modules you should know: bcrypt</description>
      <content:encoded><![CDATA[<p>Next in our series of <a href="http://www.topdog.za.net/category/pymysk/"><em>Python modules you should know</em></a>
is bcrypt. I previously <a href="http://www.topdog.za.net/2012/04/23/python-modules-you-should-know:-passlib/">wrote</a>
about the passlib package which you can use to manage passwords, in some cases a fully
featured password management package is not what you want. The bcrypt package is small
and allows you to manage passwords using <a href="http://www.openbsd.org/papers/bcrypt-paper.ps">OpenBSD's BCrypt hashing scheme</a>.
It is in fact used by passlib in the <a href="http://packages.python.org/passlib/install.html#optional-libraries">background</a>
to handle BCrypt hashes.</p>
<h2>Home page</h2>
<ul>
<li><a href="http://www.mindrot.org/projects/py-bcrypt/">http://www.mindrot.org/projects/py-bcrypt/</a></li>
</ul>
<h2>Use</h2>
<p>py-bcrypt is a Python wrapper of OpenBSD's Blowfish password hashing code, as described in
"A Future-Adaptable Password Scheme" by Niels Provos and David Mazières.</p>
<p>This system hashes passwords using a version of Bruce Schneier's Blowfish block cipher with
modifications designed to raise the cost of off-line password cracking and frustrate fast
hardware implementation. The computation cost of the algorithm is parametised, so it can be
increased as computers get faster. The intent is to make a compromise of a password database
less likely to result in an attacker gaining knowledge of the plaintext
passwords (e.g. using John the Ripper).</p>
<p>The module allows you to <a href="http://codahale.com/how-to-safely-store-a-password/">safely store passwords</a>
using Python.</p>
<h2>Installation</h2>
<pre><code>pip install py-bcrypt
</code></pre>
<h2>Usage</h2>
<p>The usage is very simple.</p>
<div class="pygments_murphy"><pre><span class="kn">import</span> <span class="nn">bcrypt</span>
<span class="c"># generate the hash</span>
<span class="n">hashed</span> <span class="o">=</span> <span class="n">bcrypt</span><span class="o">.</span><span class="n">hashpw</span><span class="p">(</span><span class="s">&#39;password&#39;</span><span class="p">,</span> <span class="n">bcrypt</span><span class="o">.</span><span class="n">gensalt</span><span class="p">())</span>
<span class="c"># compare hash with a password</span>
<span class="k">if</span> <span class="n">bcrypt</span><span class="o">.</span><span class="n">hashpw</span><span class="p">(</span><span class="s">&#39;password&#39;</span><span class="p">,</span> <span class="n">hashed</span><span class="p">)</span> <span class="o">==</span> <span class="n">hashed</span><span class="p">:</span>
    <span class="k">print</span> <span class="s">&quot;matched&quot;</span>
<span class="k">else</span><span class="p">:</span>
    <span class="k">print</span> <span class="s">&quot;failed&quot;</span>
<span class="k">print</span> <span class="n">hashed</span>
</pre></div>

<p>Output:</p>
<pre><code>'$2a$12$rK9jIjKu3wRMEf/E6pv9uuqXFmeg.WlBA3jT7uwKb71o1ZSt1xIIW'
</code></pre>
<p>Thats it, nice and sweet.</p>]]></content:encoded>
    </item>
    <item>
      <title>Python modules you should know: pexpect</title>
      <link>http://www.topdog.za.net/2012/04/25/python-modules-you-should-know:-pexpect</link>
      <pubDate>Wed, 25 Apr 2012 07:25:00 SAST</pubDate>
      <category><![CDATA[Python]]></category>
      <category><![CDATA[PyMYSK]]></category>
      <category><![CDATA[Howto]]></category>
      <guid isPermaLink="true">http://www.topdog.za.net/2012/04/25/python-modules-you-should-know:-pexpect</guid>
      <description>Python modules you should know: pexpect</description>
      <content:encoded><![CDATA[<p>Next in our series of <a href="http://www.topdog.za.net/category/pymysk/"><em>Python modules you should know</em></a>
is pexpect.</p>
<h2>Home page</h2>
<ul>
<li><a href="http://www.noah.org/wiki/Pexpect">http://www.noah.org/wiki/Pexpect</a></li>
</ul>
<h2>Use</h2>
<p>Pexpect is a pure Python module that makes Python a better tool for controlling and
automating other programs. Pexpect is similar to the Don Libes <strong>Expect</strong> system, but
Pexpect as a different interface that is easier to understand. </p>
<p>It runs programs and watches output. When output matches a given pattern Pexpect can
respond as if a human were typing responses.</p>
<p>Pexpect can be used for automation, testing, and screen scraping. Pexpect can be used
for automating interactive console applications such as ssh, ftp, passwd, telnet, etc.</p>
<p>Unlike other Expect-like modules for Python Pexpect does not require TCL or Expect nor
does it require C extensions to be compiled. It should work on any platform that supports
the standard Python pty module.</p>
<h2>Installation</h2>
<pre><code>pip install pexpect
</code></pre>
<h2>Usage</h2>
<p>In the following example i will show you how to automate the creation of a super user
in Django. The Django <a href="https://docs.djangoproject.com/en/1.3/topics/auth/#creating-superusers">manage.py</a>
command is used to create user accounts, it has a no input <strong>--noinput</strong> option but this
option does not allow you to set the password. With this example you are able to create
the user account and set the password as if you were typing in the responses.</p>
<div class="pygments_murphy"><pre><span class="kn">import</span> <span class="nn">pexpect</span>
<span class="n">child</span> <span class="o">=</span> <span class="n">pexpect</span><span class="o">.</span><span class="n">spawn</span><span class="p">(</span><span class="s">&#39;manage.py createsuperuser&#39;</span><span class="p">)</span>
<span class="n">child</span><span class="o">.</span><span class="n">expect</span><span class="p">(</span><span class="s">&#39;Username: &#39;</span><span class="p">)</span>
<span class="n">child</span><span class="o">.</span><span class="n">sendline</span><span class="p">(</span><span class="s">&#39;username&#39;</span><span class="p">)</span>
<span class="n">child</span><span class="o">.</span><span class="n">expect</span><span class="p">(</span><span class="s">&#39;E-mail address: &#39;</span><span class="p">)</span>
<span class="n">child</span><span class="o">.</span><span class="n">sendline</span><span class="p">(</span><span class="s">&#39;username@example.com&#39;</span><span class="p">)</span>
<span class="n">child</span><span class="o">.</span><span class="n">expect</span><span class="p">(</span><span class="s">&#39;Password: &#39;</span><span class="p">)</span>
<span class="n">child</span><span class="o">.</span><span class="n">sendline</span><span class="p">(</span><span class="s">&#39;my weak password&#39;</span><span class="p">)</span>
<span class="n">child</span><span class="o">.</span><span class="n">expect</span><span class="p">(</span><span class="s">&#39;</span><span class="se">\r\n</span><span class="s">&#39;</span><span class="p">)</span>
<span class="n">child</span><span class="o">.</span><span class="n">expect</span><span class="p">(</span><span class="s">&#39;Password \(again\): &#39;</span><span class="p">)</span>
<span class="n">child</span><span class="o">.</span><span class="n">sendline</span><span class="p">(</span><span class="s">&#39;my weak password&#39;</span><span class="p">)</span>
</pre></div>

<p>You can use pexpect to do all the things you could do using expect, the source tar ball
contains several examples, showing how you can automate the following:</p>
<ul>
<li>Detect if one IP address is taking up an excessive number of connections by running netstat</li>
<li>Creates SSH connections to a list of hosts and send commands to all the hosts</li>
<li>Start a subshell and log all input and output to a file like the script command</li>
<li>Clean up binary files improperly added to CVS</li>
<li>Connect to an ftp site and do a few ftp tasks</li>
<li>Run a sequence of commands on a remote host using SSH</li>
<li>Login to each given server and change the password of the given user</li>
<li>Starts an SSH tunnel, monitor the connection and restarts the tunnel if it goes down</li>
</ul>
<h2>And there is more</h2>
<p>If you would like to script a process that requires human interaction then pexpect is for
you, please refer to the <a href="http://www.noah.org/wiki/Pexpect#API_Documentation">documentation</a>
for more information. </p>]]></content:encoded>
    </item>
  </channel>
</rss>
