<?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>Thu, 17 May 2012 13:18:34 GMT</pubDate>
    <generator>Blogofile</generator>
    <sy:updatePeriod>hourly</sy:updatePeriod>
    <sy:updateFrequency>1</sy:updateFrequency>
    <item>
      <title>Crate.io, A Next Generation Python Packaging Index</title>
      <link>http://www.topdog.za.net/2012/05/16/crate.io,-a-next-generation-python-packaging-index</link>
      <pubDate>Wed, 16 May 2012 07:30:00 SAST</pubDate>
      <category><![CDATA[Python]]></category>
      <guid isPermaLink="true">http://www.topdog.za.net/2012/05/16/crate.io,-a-next-generation-python-packaging-index</guid>
      <description>Crate.io, A Next Generation Python Packaging Index</description>
      <content:encoded><![CDATA[<p>I just came across <a href="https://crate.io">crate.io</a> a PyPI Mirror/Python Package
Index that was written to make it easy to discover packages, evaluate them for
usefulness, and then install them.</p>
<p>I am impressed, the interface to me is more functional than the dated
<a href="http://pypi.python.org/pypi/">Cheeseshop</a>.</p>
<p>It uses Django/Postgesql/Redis/Celery and the Backend and frontend code is
available for download on <a href="https://github.com/crateio">github</a></p>
<p>You can find my <a href="https://crate.io/packages/baruwa/">Baruwa</a> project on crate.io</p>]]></content:encoded>
    </item>
    <item>
      <title>Block Spam from domains on the South Africa ISPA Spam Hall of Shame using DNSBL Part2</title>
      <link>http://www.topdog.za.net/2012/05/11/block-spam-from-domains-on-the-south-africa-ispa-spam-hall-of-shame-using-dnsbl-part2</link>
      <pubDate>Fri, 11 May 2012 07:30:00 SAST</pubDate>
      <category><![CDATA[Postfix]]></category>
      <category><![CDATA[Tips]]></category>
      <category><![CDATA[Exim]]></category>
      <category><![CDATA[Email]]></category>
      <category><![CDATA[Linux]]></category>
      <guid isPermaLink="true">http://www.topdog.za.net/2012/05/11/block-spam-from-domains-on-the-south-africa-ispa-spam-hall-of-shame-using-dnsbl-part2</guid>
      <description>Block Spam from domains on the South Africa ISPA Spam Hall of Shame using DNSBL Part2</description>
      <content:encoded><![CDATA[<p>I previously <a href="http://www.topdog.za.net/2012/04/22/tip:-block-spam-from-domains-on-the-south-africa-ispa-spam-hall-of-shame-using-dnsbl/">wrote</a>
about how to block domains named in the ISPA Spam Hall of Shame using DNSBL at
SMTP time, these domains have now resorted to using 3rd party senders to try and get their Junk
through. Because they are using 3rd party senders the envelope from address is no longer the one
that is listed on the hall of shame.</p>
<p>In this post i will describe how you can catch the mail that has slipped through your SMTP DNSBL
checks.</p>
<p>To identify these messages i use <a href="http://spamassassin.apache.org/">Spamassassin's</a> <a href="http://search.cpan.org/dist/Mail-SpamAssassin/lib/Mail/SpamAssassin/Plugin/URIDNSBL.pm">URIDNSBL plugin</a>
which extracts the uri's in an email and checks each of them against the DNSBL.</p>
<p>Create a file called ispa.cf in your Spamassassin configuration directory usually
/etc/mail/spamassassin with the following contents</p>
<pre><code># /etc/mail/spamassassin/ispa.cf
urirhsbl        URIBL_BARUWA    ispa.rbl.baruwa.net.   A
body            URIBL_BARUWA    eval:check_uridnsbl(’URIBL_BARUWA’)
describe        URIBL_BARUWA    Contains a URL listed in the Baruwa blocklist
score           URIBL_BARUWA    7.0
</code></pre>
<p>Restart Spamassassin and email from those domains that by pass the DNSBL checks by using 3rd
party senders should now be tagged as Spam by Spamassassin with a score of 7.0</p>
<p>Feedback is welcome, as Spam fighting is always an on going battle.</p>]]></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>
      <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>

<p><span class="kn">from</span> <span class="nn">dkim</span> <span class="kn">import</span> <span class="n">sign</span></p>
<p><span class="n">body</span> <span class="o">=</span> <span class="s">&quot;&quot;&quot;Hi There,</span></p>
<p><span class="s">This is a simple message that will be signed by pydkim</span></p>
<p><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></p>
<p><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>
<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>

<p><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></p>
<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>
      <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>

<p><span class="k">if</span> <span class="n"><strong>name</strong></span> <span class="o">==</span> <span class="s">&#39;<strong>main</strong>&#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></p>
<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>
      <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>
      <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>MailScanner book now free</title>
      <link>http://www.topdog.za.net/2012/05/01/mailscanner-book-now-free</link>
      <pubDate>Tue, 01 May 2012 12:39:00 SAST</pubDate>
      <category><![CDATA[Sysadmin]]></category>
      <category><![CDATA[Security]]></category>
      <category><![CDATA[Email]]></category>
      <category><![CDATA[Linux]]></category>
      <guid isPermaLink="true">http://www.topdog.za.net/2012/05/01/mailscanner-book-now-free</guid>
      <description>MailScanner book now free</description>
      <content:encoded><![CDATA[<p><a href="http://www.jules.fm/">Julian Field</a> the author of <a href="http://www.mailscanner.info/">MailScanner</a>
and the of the MailScanner book has just announced that the MailScanner Book is now available for free.</p>
<p>So head off and <a href="http://www.mailscanner.info/files/MailScanner-Guide.pdf">get your copy</a>.</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>
      <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>
      <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>

<p><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>
<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>
      <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>
  </channel>
</rss>

