<?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>Testing SSL client certificate authentication with curl</title>
      <link>http://www.topdog.za.net/2013/03/28/testing-ssl-client-certificate-authentication-with-curl</link>
      <pubDate>Thu, 28 Mar 2013 07:40:00 SAST</pubDate>
      <category><![CDATA[Sysadmin]]></category>
      <category><![CDATA[Tips]]></category>
      <category><![CDATA[Security]]></category>
      <guid isPermaLink="true">http://www.topdog.za.net/2013/03/28/testing-ssl-client-certificate-authentication-with-curl</guid>
      <description>Testing SSL client certificate authentication with curl</description>
      <content:encoded><![CDATA[<p>When using SSL client certificate authentication you may need to
test it using command line tools.</p>
<p>To do so run the following command:</p>
<pre><code>curl -v -s -k --key client.key --cert client.pem https://servername
</code></pre>
<p>Thats it.</p>]]></content:encoded>
    </item>
    <item>
      <title>Setup a OpenVPN server on Centos 6</title>
      <link>http://www.topdog.za.net/2013/02/02/setup-a-openvpn-server-on-centos-6</link>
      <pubDate>Sat, 02 Feb 2013 07:40:00 SAST</pubDate>
      <category><![CDATA[Sysadmin]]></category>
      <category><![CDATA[Tips]]></category>
      <category><![CDATA[Security]]></category>
      <category><![CDATA[Centos]]></category>
      <guid isPermaLink="true">http://www.topdog.za.net/2013/02/02/setup-a-openvpn-server-on-centos-6</guid>
      <description>Setup a OpenVPN server on Centos 6</description>
      <content:encoded><![CDATA[<h2>EPEL Repository</h2>
<p>OpenVPN 2 is available for Centos from the EPEL repository, so you
need to have EPEL enabled.</p>
<p>If you do not have EPEL enabled run:</p>
<pre><code>rpm -Uvh http://download.fedoraproject.org/pub/epel/6/i386/epel-release-6-8.noarch.rpm
</code></pre>
<h2>Installation</h2>
<p>To install OpenVPN run:</p>
<pre><code>yum install openvpn lzo -y
</code></pre>
<h2>Configuration</h2>
<p>Setup the SSL CA and keys:</p>
<pre><code>cp -r /usr/share/openvpn/easy-rsa/2.0 /etc/openvpn/open-rsa
</code></pre>
<p>Create and customize the <code>vars</code> file <code>/etc/openvpn/open-rsa/vars</code>,
Make sure you change the <code>KEY_</code> values to your own settings</p>
<div class="pygments_murphy"><pre><span class="nb">export </span><span class="nv">EASY_RSA</span><span class="o">=</span><span class="s2">&quot;`pwd`&quot;</span>
<span class="nb">export </span><span class="nv">OPENSSL</span><span class="o">=</span><span class="s2">&quot;openssl&quot;</span>
<span class="nb">export </span><span class="nv">PKCS11TOOL</span><span class="o">=</span><span class="s2">&quot;pkcs11-tool&quot;</span>
<span class="nb">export </span><span class="nv">GREP</span><span class="o">=</span><span class="s2">&quot;grep&quot;</span>
<span class="nb">export </span><span class="nv">KEY_CONFIG</span><span class="o">=</span><span class="sb">`</span><span class="nv">$EASY_RSA</span>/whichopensslcnf <span class="nv">$EASY_RSA</span><span class="sb">`</span>
<span class="nb">export </span><span class="nv">KEY_DIR</span><span class="o">=</span><span class="s2">&quot;/etc/openvpn/keys&quot;</span>
<span class="nb">echo </span>NOTE: If you run ./clean-all, I will be doing a rm -rf on <span class="nv">$KEY_DIR</span>
<span class="nb">export </span><span class="nv">PKCS11_MODULE_PATH</span><span class="o">=</span><span class="s2">&quot;dummy&quot;</span>
<span class="nb">export </span><span class="nv">PKCS11_PIN</span><span class="o">=</span><span class="s2">&quot;dummy&quot;</span>
<span class="nb">export </span><span class="nv">KEY_SIZE</span><span class="o">=</span>1024
<span class="nb">export </span><span class="nv">CA_EXPIRE</span><span class="o">=</span>3650
<span class="nb">export </span><span class="nv">KEY_EXPIRE</span><span class="o">=</span>3650
<span class="nb">export </span><span class="nv">KEY_COUNTRY</span><span class="o">=</span><span class="s2">&quot;ZA&quot;</span>
<span class="nb">export </span><span class="nv">KEY_PROVINCE</span><span class="o">=</span><span class="s2">&quot;Gauteng&quot;</span>
<span class="nb">export </span><span class="nv">KEY_CITY</span><span class="o">=</span><span class="s2">&quot;Johannesburg&quot;</span>
<span class="nb">export </span><span class="nv">KEY_ORG</span><span class="o">=</span><span class="s2">&quot;Topdog-software&quot;</span>
<span class="nb">export </span><span class="nv">KEY_EMAIL</span><span class="o">=</span><span class="s2">&quot;andrew@topdog.za.net&quot;</span>
<span class="nb">export </span><span class="nv">KEY_CN</span><span class="o">=</span><span class="s2">&quot;Topdog-software OpenVPN CA&quot;</span>
<span class="nb">export </span><span class="nv">KEY_NAME</span><span class="o">=</span><span class="s2">&quot;tdss&quot;</span>
<span class="nb">export </span><span class="nv">KEY_OU</span><span class="o">=</span><span class="s2">&quot;Topdog-software&quot;</span>
</pre></div>

<p>Create the keys directory:</p>
<pre><code>mkdir /etc/openvpn/keys
</code></pre>
<p>Create the CA:</p>
<pre><code>cd /etc/openvpn/open-rsa
source ./vars
./clean-all
./build-ca
</code></pre>
<p>Create the servers SSL certificate (replace <code>vpn.home.topdog-software.com</code> with
name of your server):</p>
<pre><code>./build-key-server vpn.home.topdog-software.com
</code></pre>
<p>Generate Diffie Hellman parameters:</p>
<pre><code>./build-dh
</code></pre>
<p>Create the leases file:</p>
<pre><code>touch /etc/openvpn/ipp.txt
</code></pre>
<p>Create the configuration file <code>/etc/openvpn/server.conf</code>:</p>
<div class="pygments_murphy"><pre>port 1194
proto udp
dev tun
ca keys/ca.crt
cert keys/vpn.home.topdog-software.com.crt
key keys/vpn.home.topdog-software.com.key
dh keys/dh1024.pem
cipher AES-128-CBC
server 10.0.0.0 255.255.255.0
ifconfig-pool-persist ipp.txt
client-config-dir ccd
keepalive 10 120
comp-lzo
persist-key
persist-tun
status /var/log/openvpn-status.log
verb 3
</pre></div>

<p>Create iptables rules to allow traffic through:</p>
<div class="pygments_murphy"><pre>*filter
..
..
-A INPUT -p udp -m state --state NEW -m udp --dport 1194 -j ACCEPT
-A FORWARD -i tun+ -o eth0 -j ACCEPT
-A FORWARD -i eth0 -o tun+ -j ACCEPT
</pre></div>

<p>Enable packet forwarding:</p>
<pre><code>echo 1 &gt; /proc/sys/net/ipv4/ip_forward
</code></pre>
<p>Make it permanent add the following to <code>/etc/sysctl.conf</code>:</p>
<div class="pygments_murphy"><pre>net.ipv4.ip_forward = 1
</pre></div>

<p>Your OpenVPN should be ready to go, start OpenVPN:</p>
<pre><code>service openvpn start
</code></pre>
<h2>Client configuration</h2>
<p>Each client requires a certificate &amp; key pairing, lets create one:</p>
<pre><code>./build-key client1.home.topdog-software.com
</code></pre>
<p>Copy the <code>client1.home.topdog-software.com.crt</code>, <code>ca.crt</code> and
<code>client1.home.topdog-software.com.key</code> files to the OpenVPN keys
directory on the client.</p>
<p>Create the client OpenVPN configuration <code>/etc/openvpn/server.conf</code>:</p>
<div class="pygments_murphy"><pre>remote vpn.home.topdog-software.com 1194
client 
remote-cert-tls server 
dev tun0 
proto udp
resolv-retry infinite 
nobind 
persist-key 
persist-tun 
float 
ca keys/ca.crt 
cert keys/client1.home.topdog-software.com.crt
key keys/client1.home.topdog-software.com.key
cipher AES-128-CBC
comp-lzo
status /var/log/openvpn-client.log
</pre></div>

<h2>Static addresses</h2>
<p>If you want some clients to get static addresses:</p>
<pre><code>mkdir /etc/openvpn/ccd
</code></pre>
<p>Create a client file for each of the clients you want to get a static
address in <code>/etc/openvpn/ccd</code> the file name should match the CN in
the client certificate.</p>
<div class="pygments_murphy"><pre>ifconfig-push 10.0.0.2 10.0.0.1
</pre></div>]]></content:encoded>
    </item>
    <item>
      <title>Centos 6 Bonded network interfaces</title>
      <link>http://www.topdog.za.net/2013/02/01/centos-6-bonded-network-interfaces</link>
      <pubDate>Fri, 01 Feb 2013 07:40:00 SAST</pubDate>
      <category><![CDATA[Sysadmin]]></category>
      <category><![CDATA[Tips]]></category>
      <category><![CDATA[Centos]]></category>
      <guid isPermaLink="true">http://www.topdog.za.net/2013/02/01/centos-6-bonded-network-interfaces</guid>
      <description>Centos 6 Bonded network interfaces</description>
      <content:encoded><![CDATA[<p>Bonding allows you to aggregate multiple ports, providing redundancy,
fault tolerance and load balancing.</p>
<p>There are various types of bonding available but i will show how to
bond in mode 1 which is active-backup. If your interested in the other
available types please refer to the
<a href="https://www.kernel.org/doc/Documentation/networking/bonding.txt">documentation</a>.</p>
<p>In this setup i have two connections to different switches in case one
fails the other takes over and services are not disrupted.</p>
<h2>Setup bonded interface</h2>
<p>Create a file in /etc/modprobe.d called bond.conf and add the following</p>
<div class="pygments_murphy"><pre><span class="nb">alias </span>bond0 bonding
</pre></div>

<p>Create the bonded interface file /etc/sysconfig/network-scripts/ifcfg-bond0
with the following contents</p>
<div class="pygments_murphy"><pre><span class="nv">DEVICE</span><span class="o">=</span>bond0
<span class="nv">IPADDR</span><span class="o">=</span>xxx.xxx.xxx.xxx
<span class="nv">NETMASK</span><span class="o">=</span>xxx.xxx.xxx.xxx
<span class="nv">ONBOOT</span><span class="o">=</span>yes
<span class="nv">BOOTPROTO</span><span class="o">=</span>none
<span class="nv">USERCTL</span><span class="o">=</span>no
<span class="nv">BONDING_OPTS</span><span class="o">=</span><span class="s2">&quot;bond0 miimon=80 mode=1&quot;</span>
</pre></div>

<p>Modify the interfaces you want to bond to look like:</p>
<div class="pygments_murphy"><pre><span class="nv">DEVICE</span><span class="o">=</span>ethX
<span class="nv">ONBOOT</span><span class="o">=</span>yes
<span class="nv">BOOTPROTO</span><span class="o">=</span>none
<span class="nv">USERCTL</span><span class="o">=</span>no
<span class="nv">MASTER</span><span class="o">=</span>bond0
<span class="nv">SLAVE</span><span class="o">=</span>yes
</pre></div>

<p>Restart networking for the changes to take effect:</p>
<pre><code>service network restart
</code></pre>
<h2>Checking the status</h2>
<p>You can check the status of the interface by running:</p>
<pre><code>cat /proc/net/bonding/bond0
</code></pre>]]></content:encoded>
    </item>
    <item>
      <title>Commandline OpenVPN client on Mac OSX with macports</title>
      <link>http://www.topdog.za.net/2013/01/31/commandline-openvpn-client-on-mac-osx-with-macports</link>
      <pubDate>Thu, 31 Jan 2013 07:40:00 SAST</pubDate>
      <category><![CDATA[Sysadmin]]></category>
      <category><![CDATA[Mac OS X]]></category>
      <category><![CDATA[Tips]]></category>
      <category><![CDATA[Security]]></category>
      <category><![CDATA[Unix]]></category>
      <guid isPermaLink="true">http://www.topdog.za.net/2013/01/31/commandline-openvpn-client-on-mac-osx-with-macports</guid>
      <description>Commandline OpenVPN client on Mac OSX with macports</description>
      <content:encoded><![CDATA[<p>Most people use TunnelBrick to setup OpenVPN client connections on Mac OSX,
i prefer using the command line.</p>
<p>To get OpenVPN up and running off the command line is a simple process. The
commands below need to be run as a privileged user if your root account is
not enabled use sudo to run the commands.</p>
<h2>Install OpenVPN</h2>
<p>To install OpenVPN 2 from macports run:</p>
<pre><code>port install openvpn2
</code></pre>
<h2>Install TunTap</h2>
<p>To install <a href="http://tuntaposx.sourceforge.net/">TunTap</a> from macports run:</p>
<pre><code>port install tuntaposx
</code></pre>
<p>Configure it to startup at boot:</p>
<pre><code>launchctl load -w /Library/LaunchDaemons/org.macports.tuntaposx.plist
</code></pre>
<p>You need <a href="http://tuntaposx.sourceforge.net/">TunTap</a> as it allows you
to create virtual interfaces using the supplied kernel extensions.
If you don't install TunTap you will get the error
<em>Cannot allocate TUN/TAP dev dynamically</em> when you try and make a
OpenVPN connection.</p>
<h2>Configuration</h2>
<p>Create a directory to hold your configuration and keys.</p>
<pre><code>mkdir /opt/local/etc/openvpn
</code></pre>
<p>Place your keys and configuration files in /opt/local/etc/openvpn/</p>
<p>A sample client configuration is provided below.</p>
<div class="pygments_murphy"><pre>client
dev tun
proto udp
remote vpn.home.topdog-software.com 1194
nobind
resolv-retry infinite
tls-client
ca /opt/local/etc/openvpn/ca.crt
cert /opt/local/etc/openvpn/client.crt
key /opt/local/etc/openvpn/client.key
ns-cert-type server
cipher BF-CBC
tls-cipher DHE-RSA-AES256-SHA
tls-remote vpn.home.topdog-software.com
tls-auth /opt/local/etc/openvpn/tls-auth.key 1
remote-cert-tls server
comp-lzo
persist-key
persist-tun
mute-replay-warnings
verb 3
mlock
</pre></div>

<h2>Connecting</h2>
<p>To connect simply run:</p>
<pre><code>openvpn2 --config /opt/local/etc/openvpn/openvpn.conf
</code></pre>]]></content:encoded>
    </item>
    <item>
      <title>Automating translation of software using the Microsoft Translator and Python</title>
      <link>http://www.topdog.za.net/2013/01/25/automating-translation-of-software-using-the-microsoft-translator-and-python</link>
      <pubDate>Fri, 25 Jan 2013 07:40:00 SAST</pubDate>
      <category><![CDATA[Sysadmin]]></category>
      <category><![CDATA[Tips]]></category>
      <category><![CDATA[Unix]]></category>
      <category><![CDATA[Linux]]></category>
      <guid isPermaLink="true">http://www.topdog.za.net/2013/01/25/automating-translation-of-software-using-the-microsoft-translator-and-python</guid>
      <description>Automating translation of software using the Microsoft Translator and Python</description>
      <content:encoded><![CDATA[<p>The <a href="http://msdn.microsoft.com/en-us/library/dd576287.aspx">Microsoft translator</a> provides an
API that you can use for automated translation. It currently supports about 39 languages.</p>
<p>True to the nature of open source i found that someone had already written
a <a href="https://github.com/openlabs/Microsoft-Translator-Python-API">python wrapper</a>
to the API. I extended the wrapper to use the <a href="http://docs.python-requests.org/en/latest/">requests</a>
and <a href="http://polib.readthedocs.org/en/latest/">pofile</a> packages.</p>
<p>My extended script is able to read gettext Portable Object <code>PO</code> source files and translate
the strings and write the translations back into <code>PO</code> files, here by automating the whole
translation process.</p>
<h2>Source</h2>
<div class="pygments_murphy"><pre><span class="c">#!/usr/bin/env python</span>
<span class="c"># -*- coding: utf-8 -*-</span>
<span class="c"># vim: ai ts=4 sts=4 et sw=4</span>

<span class="sd">&quot;&quot;&quot;Automatic translation using m$ translator</span>
<span class="sd">    :copyright: 2012 Andrew Colin Kissa</span>
<span class="sd">    :copyright: 2011 by Openlabs Technologies &amp; Consulting (P) Limited</span>
<span class="sd">    :license: BSD, see LICENSE for more details.</span>
<span class="sd">&quot;&quot;&quot;</span>

<span class="kn">import</span> <span class="nn">os</span>
<span class="kn">import</span> <span class="nn">re</span>
<span class="kn">import</span> <span class="nn">json</span>
<span class="kn">import</span> <span class="nn">time</span>
<span class="kn">import</span> <span class="nn">urllib</span>
<span class="kn">import</span> <span class="nn">logging</span>
<span class="kn">import</span> <span class="nn">datetime</span>

<span class="kn">import</span> <span class="nn">requests</span>

<span class="kn">from</span> <span class="nn">optparse</span> <span class="kn">import</span> <span class="n">OptionParser</span>

<span class="kn">from</span> <span class="nn">polib</span> <span class="kn">import</span> <span class="n">pofile</span>

<span class="n">__all__</span> <span class="o">=</span> <span class="p">[</span><span class="s">&#39;Translator&#39;</span><span class="p">,</span> <span class="s">&#39;TranslateApiException&#39;</span><span class="p">]</span>

<span class="k">class</span> <span class="nc">ArgumentException</span><span class="p">(</span><span class="ne">Exception</span><span class="p">):</span>
    <span class="sd">&quot;&quot;&quot;Argument&quot;&quot;&quot;</span>
    <span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">message</span><span class="p">):</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">message</span> <span class="o">=</span> <span class="n">message</span><span class="o">.</span><span class="n">replace</span><span class="p">(</span><span class="s">&#39;ArgumentException: &#39;</span><span class="p">,</span> <span class="s">&#39;&#39;</span><span class="p">)</span>
        <span class="nb">super</span><span class="p">(</span><span class="n">ArgumentException</span><span class="p">,</span> <span class="bp">self</span><span class="p">)</span><span class="o">.</span><span class="n">__init__</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">message</span><span class="p">)</span>

<span class="k">class</span> <span class="nc">ArgumentOutOfRangeException</span><span class="p">(</span><span class="ne">Exception</span><span class="p">):</span>
    <span class="sd">&quot;&quot;&quot;ArgumentOutOfRange&quot;&quot;&quot;</span>
    <span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">message</span><span class="p">):</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">message</span> <span class="o">=</span> <span class="n">message</span><span class="o">.</span><span class="n">replace</span><span class="p">(</span><span class="s">&#39;ArgumentOutOfRangeException: &#39;</span><span class="p">,</span> <span class="s">&#39;&#39;</span><span class="p">)</span>
        <span class="nb">super</span><span class="p">(</span><span class="n">ArgumentOutOfRangeException</span><span class="p">,</span> <span class="bp">self</span><span class="p">)</span><span class="o">.</span><span class="n">__init__</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">message</span><span class="p">)</span>

<span class="k">class</span> <span class="nc">TranslateApiException</span><span class="p">(</span><span class="ne">Exception</span><span class="p">):</span>
    <span class="sd">&quot;&quot;&quot;TranslateApi&quot;&quot;&quot;</span>
    <span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">message</span><span class="p">,</span> <span class="o">*</span><span class="n">args</span><span class="p">):</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">message</span> <span class="o">=</span> <span class="n">message</span><span class="o">.</span><span class="n">replace</span><span class="p">(</span><span class="s">&#39;TranslateApiException: &#39;</span><span class="p">,</span> <span class="s">&#39;&#39;</span><span class="p">)</span>
        <span class="nb">super</span><span class="p">(</span><span class="n">TranslateApiException</span><span class="p">,</span> <span class="bp">self</span><span class="p">)</span><span class="o">.</span><span class="n">__init__</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">message</span><span class="p">,</span> <span class="o">*</span><span class="n">args</span><span class="p">)</span>

<span class="k">class</span> <span class="nc">Translator</span><span class="p">(</span><span class="nb">object</span><span class="p">):</span>
    <span class="sd">&quot;&quot;&quot;Implements AJAX API for the Microsoft Translator service</span>
<span class="sd">    </span>
<span class="sd">    &quot;&quot;&quot;</span>
    <span class="n">lang_url</span> <span class="o">=</span> <span class="s">&#39;http://api.microsofttranslator.com/V2/Ajax.svc/GetLanguagesForTranslate&#39;</span>
    <span class="n">oauth_url</span> <span class="o">=</span> <span class="s">&#39;https://datamarket.accesscontrol.windows.net/v2/OAuth2-13&#39;</span>
    <span class="n">translate_url</span> <span class="o">=</span> <span class="s">&quot;http://api.microsofttranslator.com/V2/Ajax.svc/Translate&quot;</span>
    <span class="n">translate_array_url</span> <span class="o">=</span> <span class="s">&quot;http://api.microsofttranslator.com/V2/Ajax.svc/TranslateArray&quot;</span>

    <span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">client_id</span><span class="p">,</span> <span class="n">client_secret</span><span class="p">,</span>
            <span class="n">scope</span><span class="o">=</span><span class="s">&quot;http://api.microsofttranslator.com&quot;</span><span class="p">,</span> <span class="n">debug</span><span class="o">=</span><span class="bp">False</span><span class="p">):</span>
        <span class="sd">&quot;&quot;&quot;</span>

<span class="sd">        :param client_id: The client ID that you specified when you registered</span>
<span class="sd">                          your application with Azure DataMarket.</span>
<span class="sd">        :param client_secret: The client secret value that you obtained when</span>
<span class="sd">                              you registered your application with Azure</span>
<span class="sd">                              DataMarket.</span>
<span class="sd">        :param scope: Defaults to http://api.microsofttranslator.com</span>
<span class="sd">        :param debug: If true, the logging level will be set to debug</span>
<span class="sd">        &quot;&quot;&quot;</span>

        <span class="bp">self</span><span class="o">.</span><span class="n">client_id</span> <span class="o">=</span> <span class="n">client_id</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">client_secret</span> <span class="o">=</span> <span class="n">client_secret</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">scope</span> <span class="o">=</span> <span class="n">scope</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">grant_type</span> <span class="o">=</span> <span class="s">&quot;client_credentials&quot;</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">access_token</span> <span class="o">=</span> <span class="bp">None</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">debug</span> <span class="o">=</span> <span class="n">debug</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">logger</span> <span class="o">=</span> <span class="n">logging</span><span class="o">.</span><span class="n">getLogger</span><span class="p">(</span><span class="s">&quot;microsofttranslator&quot;</span><span class="p">)</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">session</span> <span class="o">=</span> <span class="bp">None</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">langs</span> <span class="o">=</span> <span class="p">[]</span>
        <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">debug</span><span class="p">:</span>
            <span class="bp">self</span><span class="o">.</span><span class="n">logger</span><span class="o">.</span><span class="n">setLevel</span><span class="p">(</span><span class="n">level</span><span class="o">=</span><span class="n">logging</span><span class="o">.</span><span class="n">DEBUG</span><span class="p">)</span>

    <span class="k">def</span> <span class="nf">create_session</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
        <span class="s">&quot;create a requests session&quot;</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">session</span> <span class="o">=</span> <span class="n">requests</span><span class="o">.</span><span class="n">session</span><span class="p">()</span>

    <span class="k">def</span> <span class="nf">get_access_token</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">force</span><span class="o">=</span><span class="bp">None</span><span class="p">):</span>
        <span class="sd">&quot;&quot;&quot;</span>
<span class="sd">        .. note::</span>
<span class="sd">            The value of access token can be used for subsequent calls to the</span>
<span class="sd">            Microsoft Translator API. The access token expires after 10</span>
<span class="sd">            minutes. It is always better to check elapsed time between time at</span>
<span class="sd">            which token issued and current time. If elapsed time exceeds 10</span>
<span class="sd">            minute time period renew access token by following obtaining</span>
<span class="sd">            access token procedure.</span>

<span class="sd">        :return: The access token to be used with subsequent requests</span>
<span class="sd">        &quot;&quot;&quot;</span>
        <span class="n">args</span> <span class="o">=</span> <span class="n">urllib</span><span class="o">.</span><span class="n">urlencode</span><span class="p">({</span>
            <span class="s">&#39;client_id&#39;</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">client_id</span><span class="p">,</span>
            <span class="s">&#39;client_secret&#39;</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">client_secret</span><span class="p">,</span>
            <span class="s">&#39;scope&#39;</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">scope</span><span class="p">,</span>
            <span class="s">&#39;grant_type&#39;</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">grant_type</span>
        <span class="p">})</span>

        <span class="k">if</span> <span class="ow">not</span> <span class="bp">self</span><span class="o">.</span><span class="n">session</span> <span class="ow">or</span> <span class="n">force</span><span class="p">:</span>
            <span class="bp">self</span><span class="o">.</span><span class="n">create_session</span><span class="p">()</span>

        <span class="n">response</span> <span class="o">=</span> <span class="n">json</span><span class="o">.</span><span class="n">loads</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">session</span><span class="o">.</span><span class="n">post</span><span class="p">(</span>
            <span class="bp">self</span><span class="o">.</span><span class="n">oauth_url</span><span class="p">,</span>
            <span class="n">data</span><span class="o">=</span><span class="n">args</span>
        <span class="p">)</span><span class="o">.</span><span class="n">content</span><span class="p">)</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">access_token</span> <span class="o">=</span> <span class="n">response</span><span class="p">[</span><span class="s">&#39;access_token&#39;</span><span class="p">]</span>
        <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">access_token</span>

    <span class="k">def</span> <span class="nf">call</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">url</span><span class="p">,</span> <span class="n">params</span><span class="p">):</span>
        <span class="sd">&quot;&quot;&quot;Calls the given url with the params urlencoded</span>
<span class="sd">        &quot;&quot;&quot;</span>
        <span class="k">if</span> <span class="ow">not</span> <span class="bp">self</span><span class="o">.</span><span class="n">access_token</span><span class="p">:</span>
            <span class="bp">self</span><span class="o">.</span><span class="n">get_access_token</span><span class="p">()</span>

        <span class="k">if</span> <span class="ow">not</span> <span class="bp">self</span><span class="o">.</span><span class="n">session</span><span class="p">:</span>
            <span class="bp">self</span><span class="o">.</span><span class="n">create_session</span><span class="p">()</span>

        <span class="n">headers</span> <span class="o">=</span> <span class="p">{</span><span class="s">&#39;Authorization&#39;</span><span class="p">:</span> <span class="s">&#39;Bearer </span><span class="si">%s</span><span class="s">&#39;</span> <span class="o">%</span> <span class="bp">self</span><span class="o">.</span><span class="n">access_token</span><span class="p">}</span>
        <span class="n">translation_url</span> <span class="o">=</span> <span class="s">&#39;</span><span class="si">%s</span><span class="s">?</span><span class="si">%s</span><span class="s">&#39;</span> <span class="o">%</span> <span class="p">(</span><span class="n">url</span><span class="p">,</span> <span class="n">urllib</span><span class="o">.</span><span class="n">urlencode</span><span class="p">(</span><span class="n">params</span><span class="p">))</span>
        <span class="n">response</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">session</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="n">translation_url</span><span class="p">,</span> <span class="n">headers</span><span class="o">=</span><span class="n">headers</span><span class="p">)</span>
        <span class="n">retval</span> <span class="o">=</span> <span class="n">json</span><span class="o">.</span><span class="n">loads</span><span class="p">(</span><span class="n">response</span><span class="o">.</span><span class="n">content</span><span class="o">.</span><span class="n">decode</span><span class="p">(</span><span class="s">&quot;UTF-8-sig&quot;</span><span class="p">))</span>

        <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">retval</span><span class="p">,</span> <span class="nb">basestring</span><span class="p">)</span> <span class="ow">and</span> \
                <span class="n">retval</span><span class="o">.</span><span class="n">startswith</span><span class="p">(</span><span class="s">&quot;ArgumentOutOfRangeException&quot;</span><span class="p">):</span>
            <span class="k">raise</span> <span class="n">ArgumentOutOfRangeException</span><span class="p">(</span><span class="n">retval</span><span class="p">)</span>

        <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">retval</span><span class="p">,</span> <span class="nb">basestring</span><span class="p">)</span> <span class="ow">and</span> \
                <span class="n">retval</span><span class="o">.</span><span class="n">startswith</span><span class="p">(</span><span class="s">&quot;TranslateApiException&quot;</span><span class="p">):</span>
            <span class="k">raise</span> <span class="n">TranslateApiException</span><span class="p">(</span><span class="n">retval</span><span class="p">)</span>

        <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">retval</span><span class="p">,</span> <span class="nb">basestring</span><span class="p">)</span> <span class="ow">and</span> \
                <span class="n">retval</span><span class="o">.</span><span class="n">startswith</span><span class="p">(</span><span class="s">&quot;ArgumentException&quot;</span><span class="p">):</span>
            <span class="bp">self</span><span class="o">.</span><span class="n">access_token</span> <span class="o">=</span> <span class="bp">None</span>
            <span class="k">raise</span> <span class="n">ArgumentException</span><span class="p">(</span><span class="n">retval</span><span class="p">)</span>

        <span class="k">return</span> <span class="n">retval</span>

    <span class="k">def</span> <span class="nf">languages</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
        <span class="sd">&quot;&quot;&quot;Check languages supported&quot;&quot;&quot;</span>
        <span class="k">if</span> <span class="ow">not</span> <span class="bp">self</span><span class="o">.</span><span class="n">session</span><span class="p">:</span>
            <span class="bp">self</span><span class="o">.</span><span class="n">create_session</span><span class="p">()</span>

        <span class="k">if</span> <span class="ow">not</span> <span class="bp">self</span><span class="o">.</span><span class="n">langs</span><span class="p">:</span>
            <span class="bp">self</span><span class="o">.</span><span class="n">langs</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">call</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">lang_url</span><span class="p">,</span> <span class="p">{})</span>
        <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">langs</span>

    <span class="k">def</span> <span class="nf">translate</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">text</span><span class="p">,</span> <span class="n">to_lang</span><span class="p">,</span> <span class="n">from_lang</span><span class="o">=</span><span class="bp">None</span><span class="p">,</span>
            <span class="n">content_type</span><span class="o">=</span><span class="s">&#39;text/plain&#39;</span><span class="p">):</span>
        <span class="sd">&quot;&quot;&quot;Translates a text string from one language to another.</span>

<span class="sd">        :param text: A string representing the text to translate.</span>
<span class="sd">        :param to_lang: A string representing the language code to</span>
<span class="sd">            translate the text into.</span>
<span class="sd">        :param from_lang: A string representing the language code of the</span>
<span class="sd">            translation text. If left None the response will include the</span>
<span class="sd">            result of language auto-detection. (Default: None)</span>
<span class="sd">        :param content_type: The format of the text being translated.</span>
<span class="sd">            The supported formats are &quot;text/plain&quot; and &quot;text/html&quot;. Any HTML</span>
<span class="sd">            needs to be well-formed.</span>
<span class="sd">        &quot;&quot;&quot;</span>
        <span class="n">params</span> <span class="o">=</span> <span class="p">{</span>
            <span class="s">&#39;text&#39;</span><span class="p">:</span> <span class="n">text</span><span class="o">.</span><span class="n">encode</span><span class="p">(</span><span class="s">&#39;utf8&#39;</span><span class="p">),</span>
            <span class="s">&#39;to&#39;</span><span class="p">:</span> <span class="n">to_lang</span><span class="p">,</span>
            <span class="s">&#39;contentType&#39;</span><span class="p">:</span> <span class="n">content_type</span><span class="p">,</span>
            <span class="s">&#39;category&#39;</span><span class="p">:</span> <span class="s">&#39;general&#39;</span><span class="p">,</span>
            <span class="p">}</span>
        <span class="k">if</span> <span class="n">from_lang</span> <span class="ow">is</span> <span class="ow">not</span> <span class="bp">None</span><span class="p">:</span>
            <span class="n">params</span><span class="p">[</span><span class="s">&#39;from&#39;</span><span class="p">]</span> <span class="o">=</span> <span class="n">from_lang</span>
        <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">call</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">translate_url</span><span class="p">,</span> <span class="n">params</span><span class="p">)</span>

    <span class="k">def</span> <span class="nf">translate_array</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">texts</span><span class="p">,</span> <span class="n">to_lang</span><span class="p">,</span> <span class="n">from_lang</span><span class="o">=</span><span class="bp">None</span><span class="p">,</span> <span class="o">**</span><span class="n">options</span><span class="p">):</span>
        <span class="sd">&quot;&quot;&quot;Translates an array of text strings from one language to another.</span>

<span class="sd">        :param texts: A list containing texts for translation.</span>
<span class="sd">        :param to_lang: A string representing the language code to </span>
<span class="sd">            translate the text into.</span>
<span class="sd">        :param from_lang: A string representing the language code of the </span>
<span class="sd">            translation text. If left None the response will include the </span>
<span class="sd">            result of language auto-detection. (Default: None)</span>
<span class="sd">        :param options: A TranslateOptions element containing the values below. </span>
<span class="sd">            They are all optional and default to the most common settings.</span>

<span class="sd">                Category: A string containing the category (domain) of the </span>
<span class="sd">                    translation. Defaults to &quot;general&quot;.</span>
<span class="sd">                ContentType: The format of the text being translated. The </span>
<span class="sd">                    supported formats are &quot;text/plain&quot; and &quot;text/html&quot;. Any </span>
<span class="sd">                    HTML needs to be well-formed.</span>
<span class="sd">                Uri: A string containing the content location of this </span>
<span class="sd">                    translation.</span>
<span class="sd">                User: A string used to track the originator of the submission.</span>
<span class="sd">                State: User state to help correlate request and response. The </span>
<span class="sd">                    same contents will be returned in the response.</span>
<span class="sd">        &quot;&quot;&quot;</span>
        <span class="n">options</span> <span class="o">=</span> <span class="p">{</span>
            <span class="s">&#39;Category&#39;</span><span class="p">:</span> <span class="s">&quot;general&quot;</span><span class="p">,</span>
            <span class="s">&#39;Contenttype&#39;</span><span class="p">:</span> <span class="s">&quot;text/plain&quot;</span><span class="p">,</span>
            <span class="s">&#39;Uri&#39;</span><span class="p">:</span> <span class="s">&#39;&#39;</span><span class="p">,</span>
            <span class="s">&#39;User&#39;</span><span class="p">:</span> <span class="s">&#39;default&#39;</span><span class="p">,</span>
            <span class="s">&#39;State&#39;</span><span class="p">:</span> <span class="s">&#39;&#39;</span>
            <span class="p">}</span><span class="o">.</span><span class="n">update</span><span class="p">(</span><span class="n">options</span><span class="p">)</span>
        <span class="n">params</span> <span class="o">=</span> <span class="p">{</span>
            <span class="s">&#39;texts&#39;</span><span class="p">:</span> <span class="n">json</span><span class="o">.</span><span class="n">dumps</span><span class="p">(</span><span class="n">texts</span><span class="p">),</span>
            <span class="s">&#39;to&#39;</span><span class="p">:</span> <span class="n">to_lang</span><span class="p">,</span>
            <span class="s">&#39;options&#39;</span><span class="p">:</span> <span class="n">json</span><span class="o">.</span><span class="n">dumps</span><span class="p">(</span><span class="n">options</span><span class="p">),</span>
            <span class="p">}</span>
        <span class="k">if</span> <span class="n">from_lang</span> <span class="ow">is</span> <span class="ow">not</span> <span class="bp">None</span><span class="p">:</span>
            <span class="n">params</span><span class="p">[</span><span class="s">&#39;from&#39;</span><span class="p">]</span> <span class="o">=</span> <span class="n">from_lang</span>

        <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">call</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">translate_array_url</span><span class="p">,</span> <span class="n">params</span><span class="p">)</span>

<span class="k">def</span> <span class="nf">format_date</span><span class="p">():</span>
    <span class="s">&quot;Return a date string in required format&quot;</span>
    <span class="k">return</span> <span class="n">time</span><span class="o">.</span><span class="n">strftime</span><span class="p">(</span><span class="s">&quot;%Y-%m-</span><span class="si">%d</span><span class="s"> %R+0200&quot;</span><span class="p">,</span> <span class="n">time</span><span class="o">.</span><span class="n">strptime</span><span class="p">(</span><span class="n">time</span><span class="o">.</span><span class="n">ctime</span><span class="p">()))</span>

<span class="k">def</span> <span class="nf">first_pass</span><span class="p">(</span><span class="n">items</span><span class="p">,</span> <span class="n">thestring</span><span class="p">):</span>
    <span class="s">&quot;replace </span><span class="si">%(xxx)s</span><span class="s"> vars&quot;</span>
    <span class="k">for</span> <span class="n">item</span> <span class="ow">in</span> <span class="n">items</span><span class="p">:</span>
        <span class="n">thestring</span> <span class="o">=</span> <span class="n">thestring</span><span class="o">.</span><span class="n">replace</span><span class="p">(</span><span class="n">item</span><span class="p">,</span> <span class="s">&#39;|^^|&#39;</span><span class="p">,</span> <span class="mi">1</span><span class="p">)</span>
    <span class="k">return</span> <span class="n">thestring</span>

<span class="k">def</span> <span class="nf">second_pass</span><span class="p">(</span><span class="n">items</span><span class="p">,</span> <span class="n">thestring</span><span class="p">):</span>
    <span class="s">&quot;replace </span><span class="si">%s</span><span class="s"> with actual </span><span class="si">%(xxx)s</span><span class="s">&quot;</span>
    <span class="k">for</span> <span class="n">item</span> <span class="ow">in</span> <span class="n">items</span><span class="p">:</span>
        <span class="n">thestring</span> <span class="o">=</span> <span class="n">thestring</span>\
                    <span class="o">.</span><span class="n">replace</span><span class="p">(</span><span class="s">&#39;|^^|&#39;</span><span class="p">,</span> <span class="n">item</span><span class="p">,</span> <span class="mi">1</span><span class="p">)</span>\
                    <span class="o">.</span><span class="n">replace</span><span class="p">(</span><span class="s">&#39;| ^ ^ |&#39;</span><span class="p">,</span> <span class="n">item</span><span class="p">,</span> <span class="mi">1</span><span class="p">)</span>
    <span class="k">return</span> <span class="n">thestring</span>

<span class="k">def</span> <span class="nf">getpofs</span><span class="p">(</span><span class="n">matched</span><span class="p">,</span> <span class="n">dirname</span><span class="p">,</span> <span class="n">files</span><span class="p">):</span>
    <span class="s">&quot;utility to get po files&quot;</span>
    <span class="n">matched</span><span class="o">.</span><span class="n">extend</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">dirname</span><span class="p">,</span> <span class="n">filename</span><span class="p">)</span>
                    <span class="k">for</span> <span class="n">filename</span> <span class="ow">in</span> <span class="n">files</span>
                    <span class="k">if</span> <span class="n">filename</span><span class="o">.</span><span class="n">endswith</span><span class="p">(</span><span class="s">&#39;.po&#39;</span><span class="p">)])</span>

<span class="k">def</span> <span class="nf">get_lang</span><span class="p">(</span><span class="n">dirname</span><span class="p">):</span>
    <span class="s">&quot;Get the language from directory name&quot;</span>
    <span class="k">return</span> <span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">basename</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">dirname</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">dirname</span><span class="p">(</span><span class="n">dirname</span><span class="p">)</span>
                <span class="p">)</span>
            <span class="p">)</span>

<span class="k">def</span> <span class="nf">process</span><span class="p">(</span><span class="n">translator</span><span class="p">,</span> <span class="n">raw_entry</span><span class="p">,</span> <span class="n">language</span><span class="p">,</span> <span class="n">sentry</span><span class="p">,</span> <span class="n">regex</span><span class="p">):</span>
    <span class="s">&quot;Process and Translate the string&quot;</span>
    <span class="n">languages_bidi</span> <span class="o">=</span> <span class="p">[</span><span class="s">&quot;he&quot;</span><span class="p">,</span> <span class="s">&quot;ar&quot;</span><span class="p">,</span> <span class="s">&quot;fa&quot;</span><span class="p">,</span> <span class="s">&quot;yi&quot;</span><span class="p">]</span>
    <span class="n">found</span> <span class="o">=</span> <span class="n">regex</span><span class="o">.</span><span class="n">findall</span><span class="p">(</span><span class="n">raw_entry</span><span class="p">)</span>
    <span class="k">if</span> <span class="n">found</span><span class="p">:</span>
        <span class="k">if</span> <span class="n">language</span> <span class="ow">in</span> <span class="n">languages_bidi</span><span class="p">:</span>
            <span class="k">return</span> <span class="bp">None</span>
        <span class="n">raw_entry</span> <span class="o">=</span> <span class="n">first_pass</span><span class="p">(</span><span class="n">found</span><span class="p">,</span> <span class="n">raw_entry</span><span class="p">)</span>
    <span class="k">if</span> <span class="n">datetime</span><span class="o">.</span><span class="n">datetime</span><span class="o">.</span><span class="n">now</span><span class="p">()</span> <span class="o">&gt;=</span> <span class="n">sentry</span><span class="p">:</span>
        <span class="k">print</span> <span class="s">&quot;Renewing token&quot;</span>
        <span class="n">translator</span><span class="o">.</span><span class="n">get_access_token</span><span class="p">(</span><span class="bp">True</span><span class="p">)</span>
        <span class="n">sentry</span> <span class="o">=</span> <span class="p">(</span><span class="n">datetime</span><span class="o">.</span><span class="n">datetime</span><span class="o">.</span><span class="n">now</span><span class="p">()</span> <span class="o">+</span>
                <span class="n">datetime</span><span class="o">.</span><span class="n">timedelta</span><span class="p">(</span><span class="n">minutes</span><span class="o">=</span><span class="mi">8</span><span class="p">))</span>
    <span class="n">new_entry</span> <span class="o">=</span> <span class="n">translator</span><span class="o">.</span><span class="n">translate</span><span class="p">(</span><span class="n">raw_entry</span><span class="p">,</span> <span class="n">language</span><span class="p">)</span>
    <span class="k">if</span> <span class="n">found</span><span class="p">:</span>
        <span class="n">new_entry</span> <span class="o">=</span> <span class="n">second_pass</span><span class="p">(</span><span class="n">found</span><span class="p">,</span> <span class="n">new_entry</span><span class="p">)</span>
    <span class="k">return</span> <span class="n">new_entry</span>

<span class="k">def</span> <span class="nf">createps</span><span class="p">(</span><span class="n">filename</span><span class="p">,</span> <span class="n">client_id</span><span class="p">,</span> <span class="n">api_key</span><span class="p">,</span> <span class="n">meta</span><span class="p">,</span> <span class="n">default_lang</span><span class="p">):</span>
    <span class="s">&quot;update po file&quot;</span>
    <span class="n">do_save</span> <span class="o">=</span> <span class="bp">False</span>
    <span class="n">trans</span> <span class="o">=</span> <span class="n">Translator</span><span class="p">(</span><span class="n">client_id</span><span class="p">,</span> <span class="n">api_key</span><span class="p">)</span>
    <span class="k">print</span> <span class="s">&quot;Processing: </span><span class="si">%s</span><span class="s">&quot;</span> <span class="o">%</span> <span class="n">filename</span>
    <span class="n">pobj</span> <span class="o">=</span> <span class="n">pofile</span><span class="p">(</span><span class="n">filename</span><span class="p">)</span>
    <span class="n">lang</span> <span class="o">=</span> <span class="n">get_lang</span><span class="p">(</span><span class="n">filename</span><span class="p">)</span>

    <span class="k">if</span> <span class="p">(</span><span class="ow">not</span> <span class="n">lang</span> <span class="ow">in</span> <span class="n">trans</span><span class="o">.</span><span class="n">languages</span><span class="p">()</span> <span class="ow">or</span> <span class="n">lang</span> <span class="o">==</span> <span class="n">default_lang</span><span class="p">)</span> <span class="ow">and</span> <span class="n">lang</span> <span class="o">!=</span> <span class="s">&#39;zh&#39;</span><span class="p">:</span>
        <span class="k">print</span> <span class="s">&quot;Language: </span><span class="si">%s</span><span class="s"> not supported by API&quot;</span> <span class="o">%</span> <span class="n">lang</span>
        <span class="k">return</span>

    <span class="k">try</span><span class="p">:</span>
        <span class="n">match_re</span> <span class="o">=</span> <span class="n">re</span><span class="o">.</span><span class="n">compile</span><span class="p">(</span><span class="s">r&#39;((?:%\([^\W]{1,}\)(?:s|d))|(?:{{\w+}}))&#39;</span><span class="p">)</span>
        <span class="n">sentry</span> <span class="o">=</span> <span class="n">datetime</span><span class="o">.</span><span class="n">datetime</span><span class="o">.</span><span class="n">now</span><span class="p">()</span> <span class="o">+</span> <span class="n">datetime</span><span class="o">.</span><span class="n">timedelta</span><span class="p">(</span><span class="n">minutes</span><span class="o">=</span><span class="mi">8</span><span class="p">)</span>
        <span class="k">if</span> <span class="n">lang</span> <span class="o">==</span> <span class="s">&#39;zh&#39;</span><span class="p">:</span>
            <span class="n">lang</span> <span class="o">=</span> <span class="s">&#39;zh-CHS&#39;</span>
        <span class="k">for</span> <span class="n">entry</span> <span class="ow">in</span> <span class="n">pobj</span><span class="o">.</span><span class="n">untranslated_entries</span><span class="p">():</span>
            <span class="k">try</span><span class="p">:</span>
                <span class="n">msgstr</span> <span class="o">=</span> <span class="n">process</span><span class="p">(</span><span class="n">trans</span><span class="p">,</span> <span class="n">entry</span><span class="o">.</span><span class="n">msgid</span><span class="p">,</span> <span class="n">lang</span><span class="p">,</span> <span class="n">sentry</span><span class="p">,</span> <span class="n">match_re</span><span class="p">)</span>
                <span class="k">if</span> <span class="n">entry</span><span class="o">.</span><span class="n">msgid_plural</span><span class="p">:</span>
                    <span class="k">if</span> <span class="n">msgstr</span><span class="p">:</span>
                        <span class="n">entry</span><span class="o">.</span><span class="n">msgstr_plural</span><span class="p">[</span><span class="s">&#39;0&#39;</span><span class="p">]</span> <span class="o">=</span> <span class="n">msgstr</span>
                    <span class="n">msgstr_plural</span> <span class="o">=</span> <span class="n">process</span><span class="p">(</span><span class="n">trans</span><span class="p">,</span> <span class="n">entry</span><span class="o">.</span><span class="n">msgid_plural</span><span class="p">,</span>
                                            <span class="n">lang</span><span class="p">,</span> <span class="n">sentry</span><span class="p">,</span> <span class="n">match_re</span><span class="p">)</span>
                    <span class="k">if</span> <span class="n">msgstr_plural</span><span class="p">:</span>
                        <span class="n">entry</span><span class="o">.</span><span class="n">msgstr_plural</span><span class="p">[</span><span class="s">&#39;1&#39;</span><span class="p">]</span> <span class="o">=</span> <span class="n">msgstr_plural</span>
                <span class="k">else</span><span class="p">:</span>
                    <span class="k">if</span> <span class="n">msgstr</span><span class="p">:</span>
                        <span class="n">entry</span><span class="o">.</span><span class="n">msgstr</span> <span class="o">=</span> <span class="n">msgstr</span>
                <span class="n">do_save</span> <span class="o">=</span> <span class="bp">True</span>
            <span class="k">except</span> <span class="p">(</span><span class="n">TranslateApiException</span><span class="p">,</span> <span class="n">ArgumentOutOfRangeException</span><span class="p">),</span> <span class="n">ermsg</span><span class="p">:</span>
                <span class="k">print</span> <span class="s">&#39;Error occured: </span><span class="si">%s</span><span class="s">&#39;</span> <span class="o">%</span> <span class="nb">str</span><span class="p">(</span><span class="n">ermsg</span><span class="p">)</span>

        <span class="k">if</span> <span class="n">do_save</span><span class="p">:</span>
            <span class="n">pobj</span><span class="o">.</span><span class="n">metadata</span><span class="o">.</span><span class="n">update</span><span class="p">(</span><span class="n">meta</span><span class="p">)</span>
            <span class="n">pobj</span><span class="o">.</span><span class="n">metadata</span><span class="p">[</span><span class="s">&#39;PO-Revision-Date&#39;</span><span class="p">]</span> <span class="o">=</span> <span class="n">format_date</span><span class="p">()</span>
            <span class="n">pobj</span><span class="o">.</span><span class="n">save</span><span class="p">(</span><span class="n">filename</span><span class="p">)</span>
    <span class="k">except</span> <span class="n">ArgumentException</span><span class="p">,</span> <span class="n">errstr</span><span class="p">:</span>
        <span class="k">print</span> <span class="s">&quot;Access Error: </span><span class="si">%s</span><span class="s">&quot;</span> <span class="o">%</span> <span class="nb">str</span><span class="p">(</span><span class="n">errstr</span><span class="p">)</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="c"># Run tings mon</span>

    <span class="n">CLIENT_ID</span> <span class="o">=</span> <span class="s">&#39;xxxxx&#39;</span>
    <span class="n">API_KEY</span> <span class="o">=</span> <span class="s">&#39;xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx&#39;</span>

    <span class="n">metadata</span> <span class="o">=</span> <span class="p">{</span>
        <span class="s">&#39;Report-Msgid-Bugs-To&#39;</span><span class="p">:</span> <span class="s">&#39;baruwa@lists.baruwa.org&#39;</span><span class="p">,</span>
        <span class="s">&#39;Last-Translator&#39;</span><span class="p">:</span> <span class="s">&#39;Andrew Colin Kissa &lt;andrew@topdog.za.net&gt;&#39;</span><span class="p">,</span>
        <span class="s">&#39;Generated-By&#39;</span><span class="p">:</span> <span class="s">&#39;auto-translate.py 0.0.1&#39;</span><span class="p">,</span>
        <span class="s">&#39;Language-Team&#39;</span><span class="p">:</span> <span class="s">&#39;Baruwa Project&#39;</span><span class="p">,</span>
    <span class="p">}</span>

    <span class="n">usage</span> <span class="o">=</span> <span class="s">&quot;usage: %prog directory&quot;</span>
    <span class="n">parser</span> <span class="o">=</span> <span class="n">OptionParser</span><span class="p">(</span><span class="n">usage</span><span class="p">)</span>
    <span class="n">parser</span><span class="o">.</span><span class="n">add_option</span><span class="p">(</span><span class="s">&#39;-s&#39;</span><span class="p">,</span> <span class="s">&#39;--source&#39;</span><span class="p">,</span> <span class="n">dest</span><span class="o">=</span><span class="s">&quot;source_lang&quot;</span><span class="p">,</span> <span class="n">default</span><span class="o">=</span><span class="s">&quot;en&quot;</span><span class="p">)</span>
    <span class="n">opts</span><span class="p">,</span> <span class="n">arguments</span> <span class="o">=</span> <span class="n">parser</span><span class="o">.</span><span class="n">parse_args</span><span class="p">()</span>

    <span class="k">if</span> <span class="nb">len</span><span class="p">(</span><span class="n">arguments</span><span class="p">)</span> <span class="o">!=</span> <span class="mi">1</span><span class="p">:</span>
        <span class="n">parser</span><span class="o">.</span><span class="n">error</span><span class="p">(</span><span class="s">&quot;Please specify the directory to process&quot;</span><span class="p">)</span>

    <span class="n">directory</span> <span class="o">=</span> <span class="n">arguments</span><span class="p">[</span><span class="mi">0</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">directory</span><span class="p">):</span>
        <span class="n">parser</span><span class="o">.</span><span class="n">error</span><span class="p">(</span><span class="s">&quot;Directory: </span><span class="si">%s</span><span class="s"> does not exist&quot;</span> <span class="o">%</span> <span class="n">directory</span><span class="p">)</span>

    <span class="k">try</span><span class="p">:</span>        
        <span class="n">pofiles</span> <span class="o">=</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">walk</span><span class="p">(</span><span class="n">directory</span><span class="p">,</span> <span class="n">getpofs</span><span class="p">,</span> <span class="n">pofiles</span><span class="p">)</span>
        <span class="n">_</span> <span class="o">=</span> <span class="p">[</span><span class="n">createps</span><span class="p">(</span><span class="n">path</span><span class="p">,</span> <span class="n">CLIENT_ID</span><span class="p">,</span> <span class="n">API_KEY</span><span class="p">,</span> <span class="n">metadata</span><span class="p">,</span> <span class="n">opts</span><span class="o">.</span><span class="n">source_lang</span><span class="p">)</span>
            <span class="k">for</span> <span class="n">path</span> <span class="ow">in</span> <span class="n">pofiles</span><span class="p">]</span>
    <span class="k">except</span> <span class="ne">KeyboardInterrupt</span><span class="p">:</span>
        <span class="k">print</span> <span class="s">&quot;</span><span class="se">\n</span><span class="s">CTRL-C pressed, exiting&quot;</span>
</pre></div>

<h2>Usage</h2>
<p>You need to obtain an access token from the Azure Marketplace instructions can be
found <a href="http://msdn.microsoft.com/en-us/library/hh454950.aspx">here</a></p>
<p>Set the <code>CLIENT_ID</code> and <code>API_KEY</code> variables in the script to the values you
obtain from Azure DataMarket.</p>
<p>Then point the script to the directory containing the <code>PO</code> files you want to translate
and let it do its thing.</p>
<pre><code>/auto-translate.py &lt;directory&gt;
</code></pre>
<h2>Download</h2>
<p>You can download the script from <a href="https://github.com/akissa/auto-translate">github</a></p>]]></content:encoded>
    </item>
    <item>
      <title>Boot into single user mode on various unixes</title>
      <link>http://www.topdog.za.net/2013/01/24/boot-into-single-user-mode-on-various-unixes</link>
      <pubDate>Thu, 24 Jan 2013 07:40:00 SAST</pubDate>
      <category><![CDATA[Sysadmin]]></category>
      <category><![CDATA[Tips]]></category>
      <category><![CDATA[Unix]]></category>
      <category><![CDATA[Linux]]></category>
      <guid isPermaLink="true">http://www.topdog.za.net/2013/01/24/boot-into-single-user-mode-on-various-unixes</guid>
      <description>Boot into single user mode on various unixes</description>
      <content:encoded><![CDATA[<h2>Linux/Grub</h2>
<p>Press <code>a</code> to append to the boot options then add <code>single</code></p>
<pre><code>grub append&gt; ro root=LABEL=/ single
</code></pre>
<h2>Solaris/OpenBoot PROM</h2>
<p>Press <code>L1+a</code> or <code>STOP+a</code> to enter OpenBoot PROM then type</p>
<pre><code>boot -s
</code></pre>
<h2>AIX</h2>
<p>Select <code>maintanance</code> mode from the boot menu or type <code>telinit S</code> on
a running machine</p>
<h2>HP-UX</h2>
<p>Interrupt the boot process when prompted and at the prompt type
<code>boot pri isl</code> to get the ISL prompt that allows you to boot into
single user mode. At the ISL prompt type</p>
<pre><code>ISL&gt; prompt: hpux -iS /stand/vmunix
</code></pre>]]></content:encoded>
    </item>
    <item>
      <title>How to update man keywords database</title>
      <link>http://www.topdog.za.net/2013/01/16/how-to-update-man-keywords-database</link>
      <pubDate>Wed, 16 Jan 2013 07:40:00 SAST</pubDate>
      <category><![CDATA[Centos]]></category>
      <category><![CDATA[Ubuntu]]></category>
      <category><![CDATA[Sysadmin]]></category>
      <category><![CDATA[Unix]]></category>
      <category><![CDATA[RHEL]]></category>
      <category><![CDATA[Linux]]></category>
      <category><![CDATA[Tips]]></category>
      <guid isPermaLink="true">http://www.topdog.za.net/2013/01/16/how-to-update-man-keywords-database</guid>
      <description>How to update man keywords database</description>
      <content:encoded><![CDATA[<p>Man keywords database allow you to search for man pages using keywords,
the database needs to be updated when ever man pages are added or removed.</p>
<p>This is how you do it for various *nix types.</p>
<h2>Debian/Ubuntu/SUSE</h2>
<pre><code>mandb
</code></pre>
<h2>RHEL/CENTOS/SL/Fedora</h2>
<pre><code>makewhatis
</code></pre>
<h2>AIX/Solaris/HP-UX</h2>
<pre><code>catman -w
</code></pre>]]></content:encoded>
    </item>
    <item>
      <title>Strongswan now supports PAM authentication</title>
      <link>http://www.topdog.za.net/2012/11/07/strongswan-now-supports-pam-authentication</link>
      <pubDate>Wed, 07 Nov 2012 07:40:00 SAST</pubDate>
      <category><![CDATA[Centos]]></category>
      <category><![CDATA[Sysadmin]]></category>
      <category><![CDATA[RHEL]]></category>
      <category><![CDATA[Linux]]></category>
      <category><![CDATA[Tips]]></category>
      <category><![CDATA[Security]]></category>
      <category><![CDATA[IPSEC]]></category>
      <guid isPermaLink="true">http://www.topdog.za.net/2012/11/07/strongswan-now-supports-pam-authentication</guid>
      <description>Strongswan now supports PAM authentication</description>
      <content:encoded><![CDATA[<p>Strongswan release 5.0.1 includes a XAuth PAM plugin which
requests username/password XAuth credentials and verifies them
against Pluggable Authentication Modules (PAM).</p>
<p>This plugin is not enabled by default to enable it you need
to add the following to your ./configure options</p>
<pre><code>--enable-xauth-pam
</code></pre>
<p>You do require the pam development headers and libraries on your
build machine to successfully compile.</p>
<h2>System Configuration</h2>
<p>The plugin is configurable in the strongswan.conf file, you are
able to change the pam service that is used for authentication.</p>
<p>By default the login pam service is used for authentication.</p>
<p>I will create a new service called ipsec for demonstration.</p>
<div class="pygments_murphy"><pre>charon {
    plugins{
        xauth-pam {
            pam_service = ipsec
        }
    }
}
</pre></div>

<p>The pam service configuration file is as follows.</p>
<div class="pygments_murphy"><pre>#%PAM-1.0
# /etc/pam.d/ipsec
auth        required      pam_env.so
auth        sufficient    pam_unix.so nullok try_first_pass
auth        requisite     pam_succeed_if.so uid &gt;= 500 quiet
auth        required      pam_deny.so

account     required      pam_unix.so
account     sufficient    pam_localuser.so
account     sufficient    pam_succeed_if.so uid &lt; 500 quiet
account     required      pam_permit.so

password    requisite     pam_cracklib.so try_first_pass retry=3 type=
password    sufficient    pam_unix.so sha512 shadow nullok try_first_pass use_authtok
password    required      pam_deny.so

session     optional      pam_keyinit.so revoke
session     required      pam_limits.so
session     [success=1 default=ignore] pam_succeed_if.so service in crond quiet use_uid
session     required      pam_unix.so
</pre></div>

<p>Now to use PAM authentication in your connections you set for XAuth:</p>
<pre><code>rightauth2=xauth-pam
</code></pre>
<p>Hybrid Authentication:</p>
<pre><code>rightauth=xauth-pam
</code></pre>
<p>You are good to go and should be able to use any pam module to
authenticate your users to your VPN. The options are endless: SQL,
LDAP, RADIUS, LOCAL etc.</p>
<h2>Related articles</h2>
<ul>
<li><a href="http://bit.ly/WABVAZ">Iphone/Ipad/Mac OSX IPSEC VPN with Strongswan 5 on Centos/RHEL 6</a></li>
<li><a href="http://bit.ly/Ujih5I">Mac OSX IPSEC VPN via command line using builtin Racoon client</a></li>
<li><a href="http://bit.ly/SN5z1k">IPSEC split tunneling VPN with Mac OSX and Strongswan 5 on Centos/RHEL 6</a></li>
</ul>]]></content:encoded>
    </item>
    <item>
      <title>Strongswan now supports Cisco unity extensions</title>
      <link>http://www.topdog.za.net/2012/11/07/strongswan-now-supports-cisco-unity-extensions</link>
      <pubDate>Wed, 07 Nov 2012 07:40:00 SAST</pubDate>
      <category><![CDATA[Centos]]></category>
      <category><![CDATA[Sysadmin]]></category>
      <category><![CDATA[RHEL]]></category>
      <category><![CDATA[Linux]]></category>
      <category><![CDATA[Tips]]></category>
      <category><![CDATA[Security]]></category>
      <category><![CDATA[IPSEC]]></category>
      <guid isPermaLink="true">http://www.topdog.za.net/2012/11/07/strongswan-now-supports-cisco-unity-extensions</guid>
      <description>Strongswan now supports Cisco unity extensions</description>
      <content:encoded><![CDATA[<p>I previously <a href="http://bit.ly/OIHOq4">wrote</a> about setting up split
tunneling on Strongswan using the <a href="http://bit.ly/NI7Mpx">attr-sql plugin</a></p>
<p>With the release of Strongswan 5.0.1 it is no longer the only way
to support split tunneling.</p>
<p>Strongswan 5.0.1 introduces the unity plugin which allows for the
configuration of split tunneling either using a charon option or
using the attr plugin which is enabled by default.</p>
<p>The unity plugin is not enabled by default to enable it you need
to add the following to your ./configure options</p>
<pre><code>--enable-unity
</code></pre>
<h2>Charon option</h2>
<p>To enable this option you need to edit the strongswan.conf file
and set</p>
<div class="pygments_murphy"><pre>charon {
    # ... other options
    cisco_unity = yes
    #...
}
</pre></div>

<p>As a client strongswan will install policies only for the received
Split-Include attributes and IPsec bypass policies for received
Local-LAN attributes.</p>
<p>As a server strongswan will send Split-Include attributes for leftsubnet
definitions containing multiple subnets to clients that support the
IKEv1 Cisco Unity Extensions.</p>
<h2>Attr plugin option</h2>
<p>It is also possible to configure split tunneling using the attr plugin.
Two new options have been added:</p>
<ul>
<li>split-include - Comma-separated list of subnets to tunnel</li>
<li>split-exclude - Comma-separated list of subnets not to tunnel</li>
</ul>
<div class="pygments_murphy"><pre>charon {
    # ... other options
    split-include = 192.168.1.0/24, 172.16.0.0/16
    split-exclude = 10.128.0.0/16
    #...
}
</pre></div>

<h2>Related articles</h2>
<ul>
<li><a href="http://bit.ly/WABVAZ">Iphone/Ipad/Mac OSX IPSEC VPN with Strongswan 5 on Centos/RHEL 6</a></li>
<li><a href="http://bit.ly/Ujih5I">Mac OSX IPSEC VPN via command line using builtin Racoon client</a></li>
<li><a href="http://bit.ly/SN5z1k">IPSEC split tunneling VPN with Mac OSX and Strongswan 5 on Centos/RHEL 6</a></li>
</ul>]]></content:encoded>
    </item>
    <item>
      <title>Mac OSX IPSEC VPN via command line using builtin Racoon client</title>
      <link>http://www.topdog.za.net/2012/09/19/mac-osx-ipsec-vpn-via-command-line-using-builtin-racoon-client</link>
      <pubDate>Wed, 19 Sep 2012 07:30:00 SAST</pubDate>
      <category><![CDATA[Mac OS X]]></category>
      <category><![CDATA[Howto]]></category>
      <category><![CDATA[Sysadmin]]></category>
      <category><![CDATA[Linux]]></category>
      <category><![CDATA[Tips]]></category>
      <category><![CDATA[Security]]></category>
      <category><![CDATA[IPSEC]]></category>
      <guid isPermaLink="true">http://www.topdog.za.net/2012/09/19/mac-osx-ipsec-vpn-via-command-line-using-builtin-racoon-client</guid>
      <description>Mac OSX IPSEC VPN via command line using builtin Racoon client</description>
      <content:encoded><![CDATA[<h2>Introduction</h2>
<p>The Mac OSX IPSEC VPN client setup via "System preferences" only supports
IPSEC/XAUTH and IPSEC/L2TP both of which give you a different IP address for
your tunnel interface. System preferences on the backend uses Racoon
so it is possible via the command line to setup a pure IPSEC connection.</p>
<p>In my <a href="http://bit.ly/WABVAZ">previous post</a> i described how to configure a Strongswan server for
use with Mac OSX, Ipad, Iphone clients. For the sake of brevity i will not
repeat that in this post.</p>
<p>This scenario assumes you are connected to a lan 10.128.1.0/24 and your
IP address is 10.128.1.2 and you are connecting to a remote network 
192.168.1.0/24 protected by an IPSEC VPN running Strongswan on a gateway with
a dynamic address being resolved via dynamic DNS.
IPSEC Authentication is done using Certificates.</p>
<h2>Configuration</h2>
<h3>Client configuration.</h3>
<p>Edit /etc/racoon/racoon.conf and add the following to the bottom.</p>
<div class="pygments_murphy"><pre>include &quot;/opt/local/etc/cmdline-ipsec.conf&quot; ;
</pre></div>

<p>Create a configuration template file /opt/local/etc/cmdline-ipsec.conf.tmpl. I am using
a template because the remote side has a dynamic ip address and racoon does
not support DNS names only IP addresses, a custom script resolves the hostname
and then generates an updated racoon configuration from this template file with the
resolved IP address.</p>
<div class="pygments_murphy"><pre>remote %SERVERIP% {
        exchange_mode main;
        ca_type x509 &quot;/opt/local/etc/pki/cacert.pem&quot;;
        certificate_type x509 &quot;/opt/local/etc/pki/example.pem&quot; &quot;/opt/local/etc/pki/example.key.pem&quot;;
        proposal_check obey;
        mode_cfg off;
        dpd_delay 360;
        nat_traversal on;
        my_identifier asn1dn;
        ike_frag on;
        script &quot;/opt/local/bin/phase1-up.sh&quot; phase1_up;
        script &quot;/opt/local/bin/phase1-down.sh&quot; phase1_down;
        lifetime time 24 hour;
        passive off;
        proposal {
                encryption_algorithm aes256;
                hash_algorithm sha512;
                authentication_method rsasig;
                dh_group 2;
       }
}

sainfo anonymous {
        lifetime time 24 hour;
        pfs_group modp2048;
        encryption_algorithm aes256;
        authentication_algorithm hmac_sha1, hmac_sha256, hmac_sha512;
        compression_algorithm deflate ;
}
</pre></div>

<p>Create the phase1 up script /opt/local/bin/phase1-up.sh</p>
<div class="pygments_murphy"><pre><span class="c">#!/bin/sh</span>

<span class="c">#</span>
<span class="c"># sa-up.sh local configuration for a new SA</span>
<span class="c">#</span>
<span class="nv">PATH</span><span class="o">=</span>/bin:/sbin:/usr/bin:/usr/sbin:/opt/local/bin:/opt/local/sbin
<span class="nv">MYIP</span><span class="o">=</span>10.128.1.2
<span class="nv">PROTECTEDNET</span><span class="o">=</span>192.168.1.0/24

<span class="nb">echo</span> <span class="nv">$@</span>
<span class="nb">echo</span> <span class="s2">&quot;LOCAL_ADDR = ${LOCAL_ADDR}&quot;</span>
<span class="nb">echo</span> <span class="s2">&quot;LOCAL_PORT = ${LOCAL_PORT}&quot;</span>
<span class="nb">echo</span> <span class="s2">&quot;REMOTE_ADDR = ${REMOTE_ADDR}&quot;</span>
<span class="nb">echo</span> <span class="s2">&quot;REMOTE_PORT = ${REMOTE_PORT}&quot;</span>

<span class="nv">LOCAL</span><span class="o">=</span><span class="s2">&quot;${LOCAL_ADDR}[${LOCAL_PORT}]&quot;</span>
<span class="nv">REMOTE</span><span class="o">=</span><span class="s2">&quot;${REMOTE_ADDR}[${REMOTE_PORT}]&quot;</span>

<span class="nb">echo</span> <span class="s2">&quot;</span>
<span class="s2">spdadd ${MYIP}/32[any] ${PROTECTEDNET}[any] any</span>
<span class="s2">       -P out ipsec esp/tunnel/${LOCAL}-${REMOTE}/require;</span>
<span class="s2">spdadd ${PROTECTEDNET} ${MYIP}[any] any</span>
<span class="s2">       -P in ipsec esp/tunnel/${REMOTE}-${LOCAL}/require;</span>
<span class="s2">&quot;</span> | setkey -c
</pre></div>

<p>Create the phase1 down script /opt/local/bin/phase1-down.sh</p>
<div class="pygments_murphy"><pre><span class="c">#!/bin/sh</span>

<span class="c">#</span>
<span class="c"># sa-down.sh local remove SA</span>
<span class="c">#</span>

<span class="nv">PATH</span><span class="o">=</span>/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin
<span class="nv">MYIP</span><span class="o">=</span>10.128.1.2
<span class="nv">PROTECTEDNET</span><span class="o">=</span>192.168.1.0/24

<span class="nb">echo</span> <span class="nv">$@</span>
<span class="nb">echo</span> <span class="s2">&quot;LOCAL_ADDR = ${LOCAL_ADDR}&quot;</span>
<span class="nb">echo</span> <span class="s2">&quot;LOCAL_PORT = ${LOCAL_PORT}&quot;</span>
<span class="nb">echo</span> <span class="s2">&quot;REMOTE_ADDR = ${REMOTE_ADDR}&quot;</span>
<span class="nb">echo</span> <span class="s2">&quot;REMOTE_PORT = ${REMOTE_PORT}&quot;</span>

<span class="nv">LOCAL</span><span class="o">=</span><span class="s2">&quot;${LOCAL_ADDR}[${LOCAL_PORT}]&quot;</span>
<span class="nv">REMOTE</span><span class="o">=</span><span class="s2">&quot;${REMOTE_ADDR}[${REMOTE_PORT}]&quot;</span>

<span class="nb">echo</span> <span class="s2">&quot;</span>
<span class="s2">deleteall ${REMOTE_ADDR} ${LOCAL_ADDR} esp;</span>
<span class="s2">deleteall ${LOCAL_ADDR} ${REMOTE_ADDR} esp; </span>
<span class="s2">spddelete ${MYIP}/32[any] ${PROTECTEDNET}[any] any</span>
<span class="s2">        -P out ipsec esp/tunnel/${LOCAL}-${REMOTE}/require;</span>
<span class="s2">spddelete ${PROTECTEDNET}[any] ${MYIP}[any] any</span>
<span class="s2">        -P in ipsec esp/tunnel/${REMOTE}-${LOCAL}/require;</span>
<span class="s2">&quot;</span> | setkey -c
</pre></div>

<p>Create the custom start script /opt/local/sbin/start-vpn</p>
<div class="pygments_murphy"><pre><span class="c">#!/bin/bash</span>
<span class="c">#</span>
<span class="c">#</span>
<span class="nv">SERVERNAME</span><span class="o">=</span><span class="s2">&quot;strongswan-example.dyndns.org&quot;</span>
<span class="nv">SERVERIP</span><span class="o">=</span><span class="k">$(</span>host <span class="nv">$SERVERNAME</span>|awk <span class="s1">&#39;{print $4}&#39;</span><span class="k">)</span>
<span class="nv">status</span><span class="o">=</span><span class="k">$(</span>racoonctl show-sa isakmp|wc -l|awk <span class="s1">&#39;{print $1}&#39;</span><span class="k">)</span>
<span class="k">if</span> <span class="o">[</span> <span class="s2">&quot;$status&quot;</span> !<span class="o">=</span> <span class="s2">&quot;2&quot;</span> <span class="o">]</span>; <span class="k">then</span>
<span class="k">   </span><span class="nb">echo</span> <span class="s2">&quot;Not connected, starting conn&quot;</span>
   sed -e <span class="s2">&quot;s:%SERVERIP%:${SERVERIP}:&quot;</span> <span class="se">\</span>
   /opt/local/etc/cmdline-ipsec.conf.tmpl &gt; /opt/local/etc/cmdline-ipsec.conf
   racoonctl reload-config
   racoonctl vpn-connect <span class="nv">$SERVERIP</span>
<span class="k">else</span>
<span class="k">   </span>racoonctl show-sa isakmp
   <span class="nb">echo</span> <span class="s2">&quot;Already connect, exiting&quot;</span>
<span class="k">fi</span>
</pre></div>

<p>Make the script executable</p>
<pre><code>chmod +x /opt/local/sbin/start-vpn
</code></pre>
<h3>Server configuration</h3>
<p>Update the ipsec.conf configuration from my previous post to add the following
conn</p>
<div class="pygments_murphy"><pre>conn rw
        leftcert=vpn.example.org.pem
        leftid=@vpn.example.org
        leftfirewall=yes
        right=%any
        rightsubnet=0.0.0.0/0
        rekey=yes
</pre></div>

<h2>Testing</h2>
<p>Open a command prompt and run the command, as root or using sudo.</p>
<pre><code>start-vpn
</code></pre>
<p>You should be able to connect to hosts on the protected network (192.168.1.0/24)</p>
<p>To stop the connection run the command.</p>
<pre><code>racoonctl vpn-disconnect strongswan-example.dyndns.org
</code></pre>
<h2>Related articles</h2>
<ul>
<li><a href="http://bit.ly/SN5z1k">IPSEC split tunneling VPN with Mac OSX and Strongswan 5 on Centos/RHEL 6</a></li>
<li><a href="http://bit.ly/WABVAZ">Iphone/Ipad/Mac OSX IPSEC VPN with Strongswan 5 on Centos/RHEL 6</a></li>
</ul>]]></content:encoded>
    </item>
  </channel>
</rss>
