<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	xmlns:creativeCommons="http://backend.userland.com/creativeCommonsRssModule"
>
<channel>
	<title>G-Loaded Journal &#187; Python</title>
	<atom:link href="http://www.g-loaded.eu/tag/python/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.g-loaded.eu</link>
	<description>An open-source software and technology related journal</description>
	<lastBuildDate>Mon, 05 Dec 2011 19:55:24 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<creativeCommons:license>http://creativecommons.org/licenses/by-nc-sa/3.0/</creativeCommons:license>
		<item>
		<title>How to create a single file of Sphinx based documentation</title>
		<link>http://www.g-loaded.eu/2010/10/29/sphinx-documentation-single-file/</link>
		<comments>http://www.g-loaded.eu/2010/10/29/sphinx-documentation-single-file/#comments</comments>
		<pubDate>Fri, 29 Oct 2010 17:17:13 +0000</pubDate>
		<dc:creator>George Notaras</dc:creator>
				<category><![CDATA[Computers]]></category>
		<category><![CDATA[Open Source]]></category>
		<category><![CDATA[Documentation]]></category>
		<category><![CDATA[Printing]]></category>
		<category><![CDATA[Python]]></category>
		<guid isPermaLink="false">http://www.g-loaded.eu/?p=2073</guid>
		<description><![CDATA[It has become common nowadays that Python projects provide their documentation in &#8220;source form&#8220;. The documentation is split into multiple files, written in restructured text, and is shipped together with some other configuration and media files for Sphinx. The user is meant to use the provided Makefile to export the documentation in various formats. This [...]]]></description>
			<content:encoded><![CDATA[<p>It has become common nowadays that Python projects provide their documentation in &#8220;<em>source form</em>&#8220;. The documentation is split into multiple files, written in <a href="http://docutils.sourceforge.net/rst.html">restructured text</a>, and is shipped together with some other configuration and media files for <a href="http://sphinx.pocoo.org">Sphinx</a>. The user is meant to use the provided <code>Makefile</code> to export the documentation in various formats. This is good and useful. Sphinx generates some nice and very readable HTML files. The only problem I encountered today was that the provided <em>Makefile</em> or <em>make.bat</em> batch script (for Windows) cannot be used to generate a <strong>single file</strong> containing the whole documentation of the project. At first, it seemed that in order to print the whole documentation I should either:<br />
<span id="more-2073"></span></p>
<ul>
<li>export the documentation into multiple HTML files using <strong>make html</strong> and then send the relevant html files one-by-one to the printer, which is insanely inconvenient, or</li>
<li>export the documentation to LaTeX format and then use a <code>tex-to-pdf</code> converter in order to merge the documentation files into a single file, which I would finally send to the printer. It should be noted that in this case, the tex-to-pdf converter had some other dependencies which summed up to 130+MB. Compressed. That&#8217;s insanely too much for converting the documentation to single-file form!!!</li>
</ul>
<p>So, I ended up <a href="http://www.g-loaded.eu/2005/10/03/search-a-string-in-multiple-files/">using grep</a> to scan the sphinx source code for expressions like <em>single</em>, <em>single file</em> etc. I soon hit <em>singlehtml</em>! Fortunately, there is a builder, named <strong>singlehtml</strong>, that produces a single HTML document for documentation that is split into multiple files. Hooray!!</p>
<p>I used the <strong>sphinx-build</strong> utility directly to generate a single HTML document containing the entire documentation. After changing to the documentation&#8217;s root directory, I issued the command:</p>
<pre class="console">
sphinx-build -b singlehtml . zzz
</pre>
<p>I finally had a single HTML file at <code>zzz/index.html</code>, which I sent to the printer and got some nice documentation in-print.</p>
<div class="cc-block"><em><a href="http://www.g-loaded.eu/2010/10/29/sphinx-documentation-single-file/">How to create a single file of Sphinx based documentation</a></em>, unless otherwise expressly stated, is licensed under a <a rel="license" href="http://creativecommons.org/licenses/by-nc-sa/3.0/">Creative Commons Attribution-Noncommercial-Share Alike 3.0 Unported License</a>. Terms and conditions beyond the scope of this license may be available at <a href="http://www.g-loaded.eu/about/disclaimer-and-license/">www.g-loaded.eu</a>.</div>
<h4>Related Articles</h4>
<ul><li><a href="http://www.g-loaded.eu/2005/11/10/using-a-cups-printer-from-command-line/" rel="bookmark">Using a CUPS printer from command line</a></li>
<li><a href="http://www.g-loaded.eu/2005/11/10/print-to-cups-printer-instances/" rel="bookmark">Print to CUPS printer instances</a></li>
<li><a href="http://www.g-loaded.eu/2007/03/05/print-a-man-page/" rel="bookmark">Print a Man Page</a></li>
<li><a href="http://www.g-loaded.eu/2009/01/22/effective-data-wiping-with-a-single-complete-overwrite/" rel="bookmark">Effective data wiping with a single complete overwrite</a></li>
<li><a href="http://www.g-loaded.eu/2005/10/01/another-way-to-create-a-text-file/" rel="bookmark">Another way to create a text file</a></li></ul>]]></content:encoded>
			<wfw:commentRss>http://www.g-loaded.eu/2010/10/29/sphinx-documentation-single-file/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	<creativeCommons:license>http://creativecommons.org/licenses/by-nc-sa/3.0/</creativeCommons:license>
	</item>
		<item>
		<title>rsapiget downloads files using the new Rapidshare API</title>
		<link>http://www.g-loaded.eu/2010/10/04/rsapiget-download-rapidshare-api/</link>
		<comments>http://www.g-loaded.eu/2010/10/04/rsapiget-download-rapidshare-api/#comments</comments>
		<pubDate>Mon, 04 Oct 2010 16:28:36 +0000</pubDate>
		<dc:creator>George Notaras</dc:creator>
				<category><![CDATA[Computers]]></category>
		<category><![CDATA[Open Source]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[Filesharing]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[rsapiget]]></category>
		<category><![CDATA[Snippet]]></category>
		<guid isPermaLink="false">http://www.g-loaded.eu/?p=1951</guid>
		<description><![CDATA[It was brought to my attention by a message in our forums that the download methods described in the &#8220;Use wget or curl to download from RapidShare Premium&#8221; article are no longer valid. Rapidshare has introduced a new API for account and file management. After a quick read of the Rapidshare API documentation, it was [...]]]></description>
			<content:encoded><![CDATA[<p>It was brought to my attention by a message in our forums that the download methods described in the &#8220;<a href="http://www.g-loaded.eu/2007/09/15/use-wget-or-curl-to-download-from-rapidshare-premium/">Use wget or curl to download from RapidShare Premium</a>&#8221; article are no longer valid. <strong>Rapidshare</strong> has introduced a new API for account and file management. After a quick read of the <a href="http://images.rapidshare.com/apidoc.txt">Rapidshare API documentation</a>, it was quite clear that the download methods that use regular cookies are not supported any more. I decided to spend some time with this API and try to write a Python script that can download files both as a free and a registered Pro user. I hereby publish this simple rapidshare client. I wrote this merely as an exercise and to compensate for the outdated information in that old article. I do not have a Rapidshare Pro account at this time and I&#8217;d say that I use such file-hosting services very rarely. So, the client has not been tested with a pro account. If you are a pro user, your feedback is welcome.</p>
<p><strong>Update</strong>: Thanks to <em>sharkic</em>&#8216;s feedback, this guide has now been improved by providing complete instructions on how to use <strong>wget</strong> and <strong>curl</strong> with the Rapidshare API. See the new sections <strong>at the end of the article</strong>.<br />
<span id="more-1951"></span></p>
<h4>The python implementation of a Rapidshare downloader</h4>
<p>Instead of writing a wrapper script around <a href="http://www.gnu.org/software/wget/">wget</a> or <a href="http://curl.haxx.se/">curl</a>, I decided to go ahead with a pure Python Rapishare downloader, which works with both free and pro accounts. The script is called <strong>rsapiget</strong>.</p>
<p>Here is the code:</p>
<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #808080; font-style: italic;">#! /usr/bin/env python</span>
<span style="color: #808080; font-style: italic;"># -*- coding: utf-8 -*-</span>
<span style="color: #808080; font-style: italic;">#</span>
<span style="color: #808080; font-style: italic;">#  rsapiget - A simple command-line downloader that supports the Rapidshare API.</span>
<span style="color: #808080; font-style: italic;">#</span>
<span style="color: #808080; font-style: italic;">#  Homepage: http://www.g-loaded.eu/rsapiget-download-rapidshare-api/</span>
<span style="color: #808080; font-style: italic;">#</span>
<span style="color: #808080; font-style: italic;">#  Copyright (c) 2010 George Notaras, G-Loaded.eu, CodeTRAX.org</span>
<span style="color: #808080; font-style: italic;">#</span>
<span style="color: #808080; font-style: italic;">#  Licensed under the Apache License, Version 2.0 (the &quot;License&quot;);</span>
<span style="color: #808080; font-style: italic;">#  you may not use this file except in compliance with the License.</span>
<span style="color: #808080; font-style: italic;">#  You may obtain a copy of the License at</span>
<span style="color: #808080; font-style: italic;">#</span>
<span style="color: #808080; font-style: italic;">#      http://www.apache.org/licenses/LICENSE-2.0</span>
<span style="color: #808080; font-style: italic;">#</span>
<span style="color: #808080; font-style: italic;">#  Unless required by applicable law or agreed to in writing, software</span>
<span style="color: #808080; font-style: italic;">#  distributed under the License is distributed on an &quot;AS IS&quot; BASIS,</span>
<span style="color: #808080; font-style: italic;">#  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.</span>
<span style="color: #808080; font-style: italic;">#  See the License for the specific language governing permissions and</span>
<span style="color: #808080; font-style: italic;">#  limitations under the License.</span>
<span style="color: #808080; font-style: italic;">#</span>
&nbsp;
<span style="color: #808080; font-style: italic;"># Configuration BEGIN</span>
LOGIN = <span style="color: #483d8b;">''</span>
PASSWORD = <span style="color: #483d8b;">''</span>
USE_SSL = <span style="color: #008000;">False</span>
VERIFY_MD5SUM = <span style="color: #008000;">False</span>
<span style="color: #808080; font-style: italic;"># Configuration END</span>
&nbsp;
__version__ = <span style="color: #483d8b;">'0.1.0'</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;">import</span> <span style="color: #dc143c;">sys</span>
<span style="color: #ff7700;font-weight:bold;">import</span> <span style="color: #dc143c;">os</span>
<span style="color: #ff7700;font-weight:bold;">import</span> <span style="color: #dc143c;">urllib</span>
<span style="color: #ff7700;font-weight:bold;">import</span> <span style="color: #dc143c;">subprocess</span>
<span style="color: #ff7700;font-weight:bold;">import</span> <span style="color: #dc143c;">time</span>
<span style="color: #ff7700;font-weight:bold;">try</span>:
    <span style="color: #ff7700;font-weight:bold;">import</span> hashlib
    <span style="color: #dc143c;">md5</span> = hashlib.<span style="color: #dc143c;">md5</span>
<span style="color: #ff7700;font-weight:bold;">except</span> <span style="color: #008000;">ImportError</span>:
    <span style="color: #ff7700;font-weight:bold;">import</span> <span style="color: #dc143c;">md5</span>
    <span style="color: #dc143c;">md5</span> = <span style="color: #dc143c;">md5</span>.<span style="color: #dc143c;">new</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;">def</span> info<span style="color: black;">&#40;</span>msg<span style="color: black;">&#41;</span>:
    <span style="color: #dc143c;">sys</span>.<span style="color: black;">stdout</span>.<span style="color: black;">write</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'%s<span style="color: #000099; font-weight: bold;">\n</span>'</span> <span style="color: #66cc66;">%</span> msg<span style="color: black;">&#41;</span>
    <span style="color: #dc143c;">sys</span>.<span style="color: black;">stdout</span>.<span style="color: black;">flush</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;">def</span> error<span style="color: black;">&#40;</span>msg<span style="color: black;">&#41;</span>:
    <span style="color: #dc143c;">sys</span>.<span style="color: black;">stderr</span>.<span style="color: black;">write</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'%s<span style="color: #000099; font-weight: bold;">\n</span>'</span> <span style="color: #66cc66;">%</span> msg<span style="color: black;">&#41;</span>
    <span style="color: #dc143c;">sys</span>.<span style="color: black;">stderr</span>.<span style="color: black;">flush</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
    <span style="color: #dc143c;">sys</span>.<span style="color: black;">exit</span><span style="color: black;">&#40;</span><span style="color: #ff4500;">1</span><span style="color: black;">&#41;</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;">def</span> transfer_progress<span style="color: black;">&#40;</span>blocks_transfered, block_size, file_size<span style="color: black;">&#41;</span>:
    percent = <span style="color: #008000;">float</span><span style="color: black;">&#40;</span><span style="color: black;">&#40;</span>blocks_transfered <span style="color: #66cc66;">*</span> block_size <span style="color: #66cc66;">*</span> <span style="color: #ff4500;">100</span><span style="color: black;">&#41;</span> / file_size<span style="color: black;">&#41;</span>
    progress = <span style="color: #008000;">float</span><span style="color: black;">&#40;</span>blocks_transfered <span style="color: #66cc66;">*</span> block_size / <span style="color: #ff4500;">1024</span><span style="color: black;">&#41;</span>
    downspeed = <span style="color: black;">&#40;</span><span style="color: #008000;">float</span><span style="color: black;">&#40;</span>blocks_transfered <span style="color: #66cc66;">*</span> block_size<span style="color: black;">&#41;</span> / <span style="color: #008000;">float</span><span style="color: black;">&#40;</span><span style="color: #dc143c;">time</span>.<span style="color: #dc143c;">time</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span> - starttime<span style="color: black;">&#41;</span><span style="color: black;">&#41;</span> / <span style="color: #ff4500;">1024</span>
    <span style="color: #dc143c;">sys</span>.<span style="color: black;">stdout</span>.<span style="color: black;">write</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;Complete: %.0f%% - Downloaded: %.2fKb - Speed: %.3fkb/s<span style="color: #000099; font-weight: bold;">\r</span>&quot;</span> <span style="color: #66cc66;">%</span> <span style="color: black;">&#40;</span>percent, progress, downspeed<span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
    <span style="color: #dc143c;">sys</span>.<span style="color: black;">stdout</span>.<span style="color: black;">flush</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;">def</span> download<span style="color: black;">&#40;</span>source, target<span style="color: black;">&#41;</span>:
    <span style="color: #ff7700;font-weight:bold;">global</span> starttime
    starttime = <span style="color: #dc143c;">time</span>.<span style="color: #dc143c;">time</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
    filename, headers = <span style="color: #dc143c;">urllib</span>.<span style="color: black;">urlretrieve</span><span style="color: black;">&#40;</span>source, target, transfer_progress<span style="color: black;">&#41;</span>
    <span style="color: #dc143c;">sys</span>.<span style="color: black;">stdout</span>.<span style="color: black;">write</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'Complete: 100%<span style="color: #000099; font-weight: bold;">\n</span>'</span><span style="color: black;">&#41;</span>
    <span style="color: #dc143c;">sys</span>.<span style="color: black;">stdout</span>.<span style="color: black;">flush</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
    <span style="color: #ff7700;font-weight:bold;">for</span> ss <span style="color: #ff7700;font-weight:bold;">in</span> headers:
        <span style="color: #ff7700;font-weight:bold;">if</span> ss.<span style="color: black;">lower</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span> == <span style="color: #483d8b;">&quot;content-disposition&quot;</span>:
            filename = headers<span style="color: black;">&#91;</span>ss<span style="color: black;">&#93;</span><span style="color: black;">&#91;</span>headers<span style="color: black;">&#91;</span>ss<span style="color: black;">&#93;</span>.<span style="color: black;">find</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;filename=&quot;</span><span style="color: black;">&#41;</span> + <span style="color: #ff4500;">9</span>:<span style="color: black;">&#93;</span>  <span style="color: #808080; font-style: italic;"># 9 is len(&quot;filename=&quot;)=9</span>
    <span style="color: #dc143c;">urllib</span>.<span style="color: black;">urlcleanup</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>     <span style="color: #808080; font-style: italic;"># Clear the cache</span>
    <span style="color: #ff7700;font-weight:bold;">return</span> filename
&nbsp;
<span style="color: #ff7700;font-weight:bold;">def</span> verify_file<span style="color: black;">&#40;</span>remote_md5sum, filename<span style="color: black;">&#41;</span>:
    f = <span style="color: #008000;">open</span><span style="color: black;">&#40;</span>filename, <span style="color: #483d8b;">&quot;rb&quot;</span><span style="color: black;">&#41;</span>
    m = <span style="color: #dc143c;">md5</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
    <span style="color: #ff7700;font-weight:bold;">while</span> <span style="color: #008000;">True</span>:
        block = f.<span style="color: black;">read</span><span style="color: black;">&#40;</span><span style="color: #ff4500;">32384</span><span style="color: black;">&#41;</span>
        <span style="color: #ff7700;font-weight:bold;">if</span> <span style="color: #ff7700;font-weight:bold;">not</span> block:
            <span style="color: #ff7700;font-weight:bold;">break</span>
        m.<span style="color: black;">update</span><span style="color: black;">&#40;</span>block<span style="color: black;">&#41;</span>
    md5sum = m.<span style="color: black;">hexdigest</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
    f.<span style="color: black;">close</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
    <span style="color: #ff7700;font-weight:bold;">return</span> md5sum == remote_md5sum
&nbsp;
<span style="color: #ff7700;font-weight:bold;">def</span> main<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>:
    <span style="color: #ff7700;font-weight:bold;">if</span> <span style="color: #008000;">len</span><span style="color: black;">&#40;</span><span style="color: #dc143c;">sys</span>.<span style="color: black;">argv</span><span style="color: black;">&#41;</span> <span style="color: #66cc66;">!</span>= <span style="color: #ff4500;">2</span>:
        error<span style="color: black;">&#40;</span><span style="color: #483d8b;">'Need Rapidshare link as argument'</span><span style="color: black;">&#41;</span>
&nbsp;
    file_link = <span style="color: #dc143c;">sys</span>.<span style="color: black;">argv</span><span style="color: black;">&#91;</span><span style="color: #ff4500;">1</span><span style="color: black;">&#93;</span>
&nbsp;
    <span style="color: #ff7700;font-weight:bold;">try</span>:
        rapidshare_com, files, fileid, filename = file_link.<span style="color: black;">rsplit</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'/'</span><span style="color: black;">&#41;</span><span style="color: black;">&#91;</span>-<span style="color: #ff4500;">4</span>:<span style="color: black;">&#93;</span>
    <span style="color: #ff7700;font-weight:bold;">except</span> <span style="color: #008000;">ValueError</span>:
        error<span style="color: black;">&#40;</span><span style="color: #483d8b;">'Invalid Rapidshare link'</span><span style="color: black;">&#41;</span>
    <span style="color: #ff7700;font-weight:bold;">if</span> <span style="color: #ff7700;font-weight:bold;">not</span> rapidshare_com.<span style="color: black;">endswith</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'rapidshare.com'</span><span style="color: black;">&#41;</span> <span style="color: #ff7700;font-weight:bold;">or</span> files <span style="color: #66cc66;">!</span>= <span style="color: #483d8b;">'files'</span>:
        error<span style="color: black;">&#40;</span><span style="color: #483d8b;">'Invalid Rapidshare link'</span><span style="color: black;">&#41;</span>
&nbsp;
    <span style="color: #ff7700;font-weight:bold;">if</span> USE_SSL:
        proto = <span style="color: #483d8b;">'https'</span>
        info<span style="color: black;">&#40;</span><span style="color: #483d8b;">'SSL is enabled'</span><span style="color: black;">&#41;</span>
    <span style="color: #ff7700;font-weight:bold;">else</span>:
        proto = <span style="color: #483d8b;">'http'</span>
&nbsp;
    <span style="color: #ff7700;font-weight:bold;">if</span> VERIFY_MD5SUM:
        info<span style="color: black;">&#40;</span><span style="color: #483d8b;">'MD5 sum verification is enabled'</span><span style="color: black;">&#41;</span>
&nbsp;
    info<span style="color: black;">&#40;</span><span style="color: #483d8b;">'Downloading: %s'</span> <span style="color: #66cc66;">%</span> file_link<span style="color: black;">&#41;</span>
&nbsp;
    <span style="color: #ff7700;font-weight:bold;">if</span> filename.<span style="color: black;">endswith</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'.html'</span><span style="color: black;">&#41;</span>:
        target_filename = filename<span style="color: black;">&#91;</span>:-<span style="color: #ff4500;">5</span><span style="color: black;">&#93;</span>
    <span style="color: #ff7700;font-weight:bold;">else</span>:
        target_filename = filename
    info<span style="color: black;">&#40;</span><span style="color: #483d8b;">'Save file as: %s'</span> <span style="color: #66cc66;">%</span> target_filename<span style="color: black;">&#41;</span>
&nbsp;
    <span style="color: #808080; font-style: italic;"># API parameters</span>
&nbsp;
    params = <span style="color: black;">&#123;</span>
        <span style="color: #483d8b;">'sub'</span>: <span style="color: #483d8b;">'download_v1'</span>,
        <span style="color: #483d8b;">'fileid'</span>: fileid,
        <span style="color: #483d8b;">'filename'</span>: filename,
        <span style="color: #483d8b;">'try'</span>: <span style="color: #483d8b;">'1'</span>,
        <span style="color: #483d8b;">'withmd5hex'</span>: <span style="color: #483d8b;">'0'</span>,
        <span style="color: black;">&#125;</span>
&nbsp;
    <span style="color: #ff7700;font-weight:bold;">if</span> VERIFY_MD5SUM:
        params.<span style="color: black;">update</span><span style="color: black;">&#40;</span><span style="color: black;">&#123;</span>
            <span style="color: #483d8b;">'withmd5hex'</span>: <span style="color: #483d8b;">'1'</span>,
            <span style="color: black;">&#125;</span><span style="color: black;">&#41;</span>
&nbsp;
    <span style="color: #ff7700;font-weight:bold;">if</span> LOGIN <span style="color: #ff7700;font-weight:bold;">and</span> PASSWORD:
        params.<span style="color: black;">update</span><span style="color: black;">&#40;</span><span style="color: black;">&#123;</span>
            <span style="color: #483d8b;">'login'</span>: LOGIN,
            <span style="color: #483d8b;">'password'</span>: PASSWORD,
            <span style="color: black;">&#125;</span><span style="color: black;">&#41;</span>
&nbsp;
    params_string = <span style="color: #dc143c;">urllib</span>.<span style="color: black;">urlencode</span><span style="color: black;">&#40;</span>params<span style="color: black;">&#41;</span>
&nbsp;
    api_url = <span style="color: #483d8b;">'%s://api.rapidshare.com/cgi-bin/rsapi.cgi'</span> <span style="color: #66cc66;">%</span> proto
&nbsp;
    <span style="color: #808080; font-style: italic;"># Get the first error response</span>
    conn = <span style="color: #dc143c;">urllib</span>.<span style="color: black;">urlopen</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'%s?%s'</span> <span style="color: #66cc66;">%</span> <span style="color: black;">&#40;</span>api_url, params_string<span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
    data = conn.<span style="color: black;">read</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
    <span style="color: #808080; font-style: italic;">#print data</span>
    conn.<span style="color: black;">close</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
&nbsp;
    <span style="color: #808080; font-style: italic;"># Parse response</span>
    <span style="color: #ff7700;font-weight:bold;">try</span>:
        key, value = data.<span style="color: black;">split</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">':'</span><span style="color: black;">&#41;</span>
    <span style="color: #ff7700;font-weight:bold;">except</span> <span style="color: #008000;">ValueError</span>:
        error<span style="color: black;">&#40;</span>data<span style="color: black;">&#41;</span>
    <span style="color: #ff7700;font-weight:bold;">try</span>:
        server, dlauth, countdown, remote_md5sum = value.<span style="color: black;">split</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">','</span><span style="color: black;">&#41;</span>
    <span style="color: #ff7700;font-weight:bold;">except</span> <span style="color: #008000;">ValueError</span>:
        error<span style="color: black;">&#40;</span>data<span style="color: black;">&#41;</span>
&nbsp;
    <span style="color: #808080; font-style: italic;"># Wait for n seconds (free accounts only)</span>
    <span style="color: #ff7700;font-weight:bold;">if</span> <span style="color: #008000;">int</span><span style="color: black;">&#40;</span>countdown<span style="color: black;">&#41;</span>:
        <span style="color: #ff7700;font-weight:bold;">for</span> t <span style="color: #ff7700;font-weight:bold;">in</span> <span style="color: #008000;">range</span><span style="color: black;">&#40;</span><span style="color: #008000;">int</span><span style="color: black;">&#40;</span>countdown<span style="color: black;">&#41;</span>, <span style="color: #ff4500;">0</span>, -<span style="color: #ff4500;">1</span><span style="color: black;">&#41;</span>:
            <span style="color: #dc143c;">sys</span>.<span style="color: black;">stdout</span>.<span style="color: black;">write</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'Waiting for %s seconds...<span style="color: #000099; font-weight: bold;">\r</span>'</span> <span style="color: #66cc66;">%</span> t<span style="color: black;">&#41;</span>
            <span style="color: #dc143c;">sys</span>.<span style="color: black;">stdout</span>.<span style="color: black;">flush</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
            <span style="color: #dc143c;">time</span>.<span style="color: black;">sleep</span><span style="color: black;">&#40;</span><span style="color: #ff4500;">1</span><span style="color: black;">&#41;</span>
        info<span style="color: black;">&#40;</span><span style="color: #483d8b;">'Waited for %s seconds. Proceeding with file download...'</span> <span style="color: #66cc66;">%</span> countdown<span style="color: black;">&#41;</span>
&nbsp;
    <span style="color: #808080; font-style: italic;"># API parameters for file download</span>
&nbsp;
    dl_params = <span style="color: black;">&#123;</span>
        <span style="color: #483d8b;">'sub'</span>: <span style="color: #483d8b;">'download_v1'</span>,
        <span style="color: #483d8b;">'fileid'</span>: fileid,
        <span style="color: #483d8b;">'filename'</span>: filename,
        <span style="color: black;">&#125;</span>
&nbsp;
    <span style="color: #ff7700;font-weight:bold;">if</span> LOGIN <span style="color: #ff7700;font-weight:bold;">and</span> PASSWORD:
        dl_params.<span style="color: black;">update</span><span style="color: black;">&#40;</span><span style="color: black;">&#123;</span>
            <span style="color: #483d8b;">'login'</span>: LOGIN,
            <span style="color: #483d8b;">'password'</span>: PASSWORD,
            <span style="color: black;">&#125;</span><span style="color: black;">&#41;</span>
    <span style="color: #ff7700;font-weight:bold;">else</span>:
        dl_params.<span style="color: black;">update</span><span style="color: black;">&#40;</span><span style="color: black;">&#123;</span>
            <span style="color: #483d8b;">'dlauth'</span>: dlauth,
            <span style="color: black;">&#125;</span><span style="color: black;">&#41;</span>
&nbsp;
    dl_params_string = <span style="color: #dc143c;">urllib</span>.<span style="color: black;">urlencode</span><span style="color: black;">&#40;</span>dl_params<span style="color: black;">&#41;</span>
&nbsp;
    download_link = <span style="color: #483d8b;">'%s://%s/cgi-bin/rsapi.cgi?%s'</span> <span style="color: #66cc66;">%</span> <span style="color: black;">&#40;</span>proto, server, dl_params_string<span style="color: black;">&#41;</span>
&nbsp;
    downloaded_filename = download<span style="color: black;">&#40;</span>download_link, target_filename<span style="color: black;">&#41;</span>
&nbsp;
    <span style="color: #ff7700;font-weight:bold;">if</span> VERIFY_MD5SUM:
        <span style="color: #ff7700;font-weight:bold;">if</span> remote_md5sum.<span style="color: black;">lower</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span> == <span style="color: #483d8b;">'not found'</span>:
            info<span style="color: black;">&#40;</span><span style="color: #483d8b;">'Remote MD5 sum is not available. Skipping MD5 sum verification...'</span><span style="color: black;">&#41;</span>
        <span style="color: #ff7700;font-weight:bold;">elif</span> downloaded_filename:
            <span style="color: #ff7700;font-weight:bold;">if</span> verify_file<span style="color: black;">&#40;</span>remote_md5sum.<span style="color: black;">lower</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>, downloaded_filename<span style="color: black;">&#41;</span>:
                info<span style="color: black;">&#40;</span><span style="color: #483d8b;">'Downloaded and verified %s'</span> <span style="color: #66cc66;">%</span> downloaded_filename<span style="color: black;">&#41;</span>
            <span style="color: #ff7700;font-weight:bold;">else</span>:
                error<span style="color: black;">&#40;</span><span style="color: #483d8b;">'The downloaded file could not be verified'</span><span style="color: black;">&#41;</span>
        <span style="color: #ff7700;font-weight:bold;">else</span>:
            error<span style="color: black;">&#40;</span><span style="color: #483d8b;">'Will not verify. File not found: %s'</span> <span style="color: #66cc66;">%</span> downloaded_filename<span style="color: black;">&#41;</span>
&nbsp;
    info<span style="color: black;">&#40;</span><span style="color: #483d8b;">'Operation Complete'</span><span style="color: black;">&#41;</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;">if</span> __name__ == <span style="color: #483d8b;">'__main__'</span>:
    <span style="color: #ff7700;font-weight:bold;">try</span>:
        main<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
    <span style="color: #ff7700;font-weight:bold;">except</span> <span style="color: #008000;">KeyboardInterrupt</span>:
        error<span style="color: black;">&#40;</span><span style="color: #483d8b;">'<span style="color: #000099; font-weight: bold;">\n</span>Aborted'</span><span style="color: black;">&#41;</span></pre></div></div>
<p>Save the code in a file called: <strong>rsapiget.py</strong></p>
<p>Usage is very simple:</p>
<pre class="console">
python rsapiget.py &lt;rapidshare_link&gt;
</pre>
<p>There are some configuration options at the top of the script you may need to check out:</p>
<ul>
<li><strong>LOGIN</strong>, <strong>PASSWORD</strong>: If you are a registered Pro user, set your username and password here. Being a pro user you will never have to wait for the download to start. Otherwise leave blank.</li>
<li><strong>USE_SSL</strong>: Set to <em>True</em> to force the client to communicate with the rapidshare servers over an encrypted connection. Note that, according to the docs, this is more expensive in terms of Rapidshare points, so it is disabled by default.</li>
<li><strong>VERIFY_MD5SUM</strong>: If this is set to <em>True</em>, the downloaded file&#8217;s integrity will be verified. The docs say that this results in more API calls than not using md5 verification, so this is disabled by default as well.</li>
</ul>
<p>Although the old article has a small download server implementation in BASH, I haven&#8217;t tested whether the latter works with this client or not.</p>
<p>Please note that this script is <em>work in progress</em> and I might update the code in the following days. So, <strong>check back often for updates</strong>.</p>
<h4>Download from Rapidshare API using wget</h4>
<p>All credit for this method goes to <strong>sharkic</strong> (see comments).</p>
<p>I admit that when I was checking out the API, I had completely overlooked the <em>withcookie</em> option of the <em>getaccountdetails_v1</em> subroutine. Also, I was not aware that it is now possible for free users to have an account with Rapidshare.</p>
<p>So, to sum <em>sharkic</em>&#8216;s feedback up, here is how it is done. The following information requires that you have signed up with Rapidshare. Of course downloading files using wget and the following instructions requires a Rapidshare Pro account.</p>
<p>First, <strong>save the cookie data</strong>. This has to be done <strong>once</strong>:</p>
<pre class="console">
wget -q -O - \
    --post-data="sub=getaccountdetails_v1&#038;withcookie=1&#038;login=LOGIN&#038;password=PASSWORD" \
    https://api.rapidshare.com/cgi-bin/rsapi.cgi \
    | grep cookie | cut -d '=' -f 2 > .rapidshare_cookie
</pre>
<p>Substitute LOGIN and PASSWORD with your Rapidshare account&#8217;s username and password.</p>
<p>Now, you can download files using:</p>
<pre class="console">
wget --no-cookies --header="Cookie: enc=`cat .rapidshare_cookie`" http://rapidshare.com/files/XXXXXXXX/test.zip
</pre>
<h4>Download from Rapidshare API using curl</h4>
<p>The <strong>curl</strong> method is a derivative of the wget method. First save the cookie with:</p>
<pre class="console">
curl --data "sub=getaccountdetails_v1&#038;withcookie=1&#038;login=LOGIN&#038;password=PASSWORD" \
    https://api.rapidshare.com/cgi-bin/rsapi.cgi \
    | grep cookie | cut -d '=' -f 2 > .rapidshare_cookie
</pre>
<p>Substitute LOGIN and PASSWORD with your Rapidshare account&#8217;s username and password.</p>
<p>Now, you can download files using:</p>
<pre class="console">
curl -L -O --cookie "enc=`cat .rapidshare_cookie`" http://rapidshare.com/files/XXXXXXXX/test.zip
</pre>
<p>Enjoy! Your feedback is welcome.</p>
<div class="cc-block"><em><a href="http://www.g-loaded.eu/2010/10/04/rsapiget-download-rapidshare-api/">rsapiget downloads files using the new Rapidshare API</a></em>, unless otherwise expressly stated, is licensed under a <a rel="license" href="http://creativecommons.org/licenses/by-nc-sa/3.0/">Creative Commons Attribution-Noncommercial-Share Alike 3.0 Unported License</a>. Terms and conditions beyond the scope of this license may be available at <a href="http://www.g-loaded.eu/about/disclaimer-and-license/">www.g-loaded.eu</a>.</div>
<h4>Related Articles</h4>
<ul><li><a href="http://www.g-loaded.eu/2007/09/15/use-wget-or-curl-to-download-from-rapidshare-premium/" rel="bookmark">Use wget or curl to download from RapidShare Premium</a></li>
<li><a href="http://www.g-loaded.eu/2007/12/01/veritar-verify-checksums-of-files-within-a-tar-archive/" rel="bookmark">VeriTAR &#8211; Verify checksums of files within a TAR archive</a></li>
<li><a href="http://www.g-loaded.eu/2007/11/04/upgraded-to-wordpress-231/" rel="bookmark">Upgraded to WordPress 2.3.1</a></li>
<li><a href="http://www.g-loaded.eu/2008/12/18/using-the-mod_dav_svn-svnparentpath-directive-with-multiple-authz-files/" rel="bookmark">Using the mod_dav_svn SVNParentPath directive with multiple authz files</a></li>
<li><a href="http://www.g-loaded.eu/2005/10/03/search-a-string-in-multiple-files/" rel="bookmark">Search for a string in multiple files</a></li></ul>]]></content:encoded>
			<wfw:commentRss>http://www.g-loaded.eu/2010/10/04/rsapiget-download-rapidshare-api/feed/</wfw:commentRss>
		<slash:comments>37</slash:comments>
	<creativeCommons:license>http://creativecommons.org/licenses/by-nc-sa/3.0/</creativeCommons:license>
	</item>
		<item>
		<title>Python SSH Server for UNIX Systems using Twisted.conch</title>
		<link>http://www.g-loaded.eu/2010/03/26/python-ssh-server-unix-twisted-conch/</link>
		<comments>http://www.g-loaded.eu/2010/03/26/python-ssh-server-unix-twisted-conch/#comments</comments>
		<pubDate>Fri, 26 Mar 2010 20:27:00 +0000</pubDate>
		<dc:creator>George Notaras</dc:creator>
				<category><![CDATA[Linux]]></category>
		<category><![CDATA[Open Source]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[Administration]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[Remote]]></category>
		<category><![CDATA[Snippet]]></category>
		<category><![CDATA[Software]]></category>
		<category><![CDATA[SSH]]></category>
		<category><![CDATA[Twisted]]></category>
		<guid isPermaLink="false">http://www.g-loaded.eu/?p=1572</guid>
		<description><![CDATA[I can still recall the excitement of the first time I tried to access and administer a remote system using SSH. Accessing my shell at a remote machine securely, being able to do local and remote port forwarding in order to access remote services through encrypted tunnels, X forwarding, secure file transfers using scp or [...]]]></description>
			<content:encoded><![CDATA[<p>I can still recall the excitement of the first time I tried to access and administer a remote system using <strong>SSH</strong>. Accessing my shell at a remote machine securely, being able to do local and remote port forwarding in order to access remote services through encrypted tunnels, X forwarding, secure file transfers using <em>scp</em> or <em>sftp</em>, <a href="http://www.g-loaded.eu/2005/11/10/ssh-with-keys/">authentication using public key infrastructure</a> are just a few of the features that justify the excitement of the first time. The only <em>Secure Shell</em> server implementation I had used all that time was the <a href="http://www.openssh.com/">OpenSSH</a> server. Although this is an open-source project, the fact that it is written in C makes it extremely difficult for me to have fun with it by making any modifications in order to implement even simple things like command filtering. This is because I have never programmed in <strong>C</strong> and do not intend to learn how to do it in the foreseeable future. So what I&#8217;ve been looking for today was a server implementation of the <strong>SSH2 protocol</strong> written in <a href="http://python.org">Python</a>. Unfortunately, there is no such project ready for immediate use. I had to hack my own! After several hours of trial and error, having written dozens of sample scripts for testing, I finally created a minimal project, called <strong>RapidSSH</strong>, in order to demonstrate how to create a fully functional SSH server with just a few lines of Python code by using <em>Twisted.conch</em>, part of the <a href="http://twistedmatrix.com">Twisted Framework</a>. Read on&#8230;<br />
<span id="more-1572"></span><br />
At first, I tried to experiment with the <a href="http://twistedmatrix.com/documents/current/conch/examples/sshsimpleserver.py">sshsimpleserver.py</a> example script that exists on the Twisted homepage. But, soon I realized that this script is there just to give an idea about how to use <code>Twisted.conch</code> and also provide a sensible starting point for your own implementations. That script was not even close in having the functionality I had in mind. After spending some time examining the Twisted source code, I found a fantastic, but completely undocumented, module: <a href="http://twistedmatrix.com/trac/browser/trunk/twisted/conch/unix.py">twisted.conch.unix</a>. Having gained some experience by my experimentation with <code>sshsimpleserver.py</code> I managed to easily put the pieces together and come up with the SSH server implementation as shown below.</p>
<p>But first, let&#8217;s install some <strong>dependencies</strong>. I assume that you will try the code on a machine aimed for testing, so I won&#8217;t be using the system&#8217;s package manager but instead use <strong>easy_install</strong> to install the needed Python modules. Other commands like <em>pip</em> could be used as well. If you do not want to mess with your system-wide python installation, just use <strong>virtualenv</strong> and <strong>pip</strong>, but I won&#8217;t go into the details about how to use these tools in the current document.</p>
<p>Install the needed dependencies:</p>
<pre class="console">
easy_install pycrypto
easy_install pyasn1
easy_install pam
easy_install twisted
</pre>
<p>Make sure you have <strong>gcc</strong> installed, because it will be needed to complete the installation of Twisted and PyCrypto.</p>
<p>I have created a project for this code at <strong>Bitbucket</strong>, called <a href="http://bitbucket.org/gnotaras/rapidssh/">RapidSSH</a>. This will make it easier to share code and ideas about SSH server implementations in Python using Twisted.</p>
<p>Filename: <code>scripts/rapidsshd_unix.py</code></p>
<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #808080; font-style: italic;">#!/usr/bin/env python</span>
<span style="color: #808080; font-style: italic;">#</span>
<span style="color: #808080; font-style: italic;"># This file is part of rapidssh - http://bitbucket.org/gnotaras/rapidssh/</span>
<span style="color: #808080; font-style: italic;">#</span>
<span style="color: #808080; font-style: italic;"># rapidssh - A set of Secure Shell (SSH) server implementations in Python</span>
<span style="color: #808080; font-style: italic;">#            using Twisted.conch, part of the Twisted Framework.</span>
<span style="color: #808080; font-style: italic;">#</span>
<span style="color: #808080; font-style: italic;"># Copyright (c) 2010 George Notaras - http://www.g-loaded.eu</span>
<span style="color: #808080; font-style: italic;">#</span>
<span style="color: #808080; font-style: italic;"># Permission is hereby granted, free of charge, to any person obtaining a copy</span>
<span style="color: #808080; font-style: italic;"># of this software and associated documentation files (the &quot;Software&quot;), to deal</span>
<span style="color: #808080; font-style: italic;"># in the Software without restriction, including without limitation the rights</span>
<span style="color: #808080; font-style: italic;"># to use, copy, modify, merge, publish, distribute, sublicense, and/or sell</span>
<span style="color: #808080; font-style: italic;"># copies of the Software, and to permit persons to whom the Software is</span>
<span style="color: #808080; font-style: italic;"># furnished to do so, subject to the following conditions:</span>
<span style="color: #808080; font-style: italic;">#</span>
<span style="color: #808080; font-style: italic;"># The above copyright notice and this permission notice shall be included in</span>
<span style="color: #808080; font-style: italic;"># all copies or substantial portions of the Software.</span>
<span style="color: #808080; font-style: italic;">#</span>
<span style="color: #808080; font-style: italic;"># THE SOFTWARE IS PROVIDED &quot;AS IS&quot;, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR</span>
<span style="color: #808080; font-style: italic;"># IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,</span>
<span style="color: #808080; font-style: italic;"># FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE</span>
<span style="color: #808080; font-style: italic;"># AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER</span>
<span style="color: #808080; font-style: italic;"># LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,</span>
<span style="color: #808080; font-style: italic;"># OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN</span>
<span style="color: #808080; font-style: italic;"># THE SOFTWARE.</span>
<span style="color: #808080; font-style: italic;">#</span>
<span style="color: #808080; font-style: italic;"># Initially based on the sshsimpleserver.py kindly published by:</span>
<span style="color: #808080; font-style: italic;"># Twisted Matrix Laboratories - http://twistedmatrix.com</span>
<span style="color: #808080; font-style: italic;">#</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;">import</span> <span style="color: #dc143c;">sys</span>
<span style="color: #ff7700;font-weight:bold;">import</span> pam
&nbsp;
<span style="color: #ff7700;font-weight:bold;">from</span> twisted.<span style="color: black;">conch</span>.<span style="color: black;">unix</span> <span style="color: #ff7700;font-weight:bold;">import</span> UnixSSHRealm
<span style="color: #ff7700;font-weight:bold;">from</span> twisted.<span style="color: black;">cred</span> <span style="color: #ff7700;font-weight:bold;">import</span> portal
<span style="color: #ff7700;font-weight:bold;">from</span> twisted.<span style="color: black;">cred</span>.<span style="color: black;">credentials</span> <span style="color: #ff7700;font-weight:bold;">import</span> IUsernamePassword
<span style="color: #ff7700;font-weight:bold;">from</span> twisted.<span style="color: black;">cred</span>.<span style="color: black;">checkers</span> <span style="color: #ff7700;font-weight:bold;">import</span> ICredentialsChecker
<span style="color: #ff7700;font-weight:bold;">from</span> twisted.<span style="color: black;">cred</span>.<span style="color: black;">error</span> <span style="color: #ff7700;font-weight:bold;">import</span> UnauthorizedLogin
<span style="color: #ff7700;font-weight:bold;">from</span> twisted.<span style="color: black;">conch</span>.<span style="color: black;">checkers</span> <span style="color: #ff7700;font-weight:bold;">import</span> SSHPublicKeyDatabase
<span style="color: #ff7700;font-weight:bold;">from</span> twisted.<span style="color: black;">conch</span>.<span style="color: black;">ssh</span> <span style="color: #ff7700;font-weight:bold;">import</span> factory, userauth, connection, keys, session
<span style="color: #ff7700;font-weight:bold;">from</span> twisted.<span style="color: black;">internet</span> <span style="color: #ff7700;font-weight:bold;">import</span> reactor, defer
<span style="color: #ff7700;font-weight:bold;">from</span> zope.<span style="color: black;">interface</span> <span style="color: #ff7700;font-weight:bold;">import</span> implements
<span style="color: #ff7700;font-weight:bold;">from</span> twisted.<span style="color: black;">python</span> <span style="color: #ff7700;font-weight:bold;">import</span> log
&nbsp;
<span style="color: #808080; font-style: italic;"># Logging</span>
<span style="color: #808080; font-style: italic;"># Currently logging to STDERR</span>
log.<span style="color: black;">startLogging</span><span style="color: black;">&#40;</span><span style="color: #dc143c;">sys</span>.<span style="color: black;">stderr</span><span style="color: black;">&#41;</span>
&nbsp;
<span style="color: #808080; font-style: italic;"># Server-side public and private keys. These are the keys found in</span>
<span style="color: #808080; font-style: italic;"># sshsimpleserver.py. Make sure you generate your own using ssh-keygen!</span>
&nbsp;
publicKey = <span style="color: #483d8b;">'ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAGEArzJx8OYOnJmzf4tfBEvLi8DVPrJ3/c9k2I/Az64fxjHf9imyRJbixtQhlH9lfNjUIx+4LmrJH5QNRsFporcHDKOTwTTYLh5KmRpslkYHRivcJSkbh/C+BR3utDS555mV'</span>
&nbsp;
privateKey = <span style="color: #483d8b;">&quot;&quot;&quot;-----BEGIN RSA PRIVATE KEY-----
MIIByAIBAAJhAK8ycfDmDpyZs3+LXwRLy4vA1T6yd/3PZNiPwM+uH8Yx3/YpskSW
4sbUIZR/ZXzY1CMfuC5qyR+UDUbBaaK3Bwyjk8E02C4eSpkabJZGB0Yr3CUpG4fw
vgUd7rQ0ueeZlQIBIwJgbh+1VZfr7WftK5lu7MHtqE1S1vPWZQYE3+VUn8yJADyb
Z4fsZaCrzW9lkIqXkE3GIY+ojdhZhkO1gbG0118sIgphwSWKRxK0mvh6ERxKqIt1
xJEJO74EykXZV4oNJ8sjAjEA3J9r2ZghVhGN6V8DnQrTk24Td0E8hU8AcP0FVP+8
PQm/g/aXf2QQkQT+omdHVEJrAjEAy0pL0EBH6EVS98evDCBtQw22OZT52qXlAwZ2
gyTriKFVoqjeEjt3SZKKqXHSApP/AjBLpF99zcJJZRq2abgYlf9lv1chkrWqDHUu
DZttmYJeEfiFBBavVYIF1dOlZT0G8jMCMBc7sOSZodFnAiryP+Qg9otSBjJ3bQML
pSTqy7c3a2AScC/YyOwkDaICHnnD3XyjMwIxALRzl0tQEKMXs6hH8ToUdlLROCrP
EhQ0wahUTCk1gKA4uPD6TMTChavbh4K63OvbKg==
-----END RSA PRIVATE KEY-----&quot;&quot;&quot;</span>
&nbsp;
&nbsp;
<span style="color: #ff7700;font-weight:bold;">class</span> PamPasswordDatabase:
    <span style="color: #483d8b;">&quot;&quot;&quot;Authentication/authorization backend using the 'login' PAM service&quot;&quot;&quot;</span>
    credentialInterfaces = IUsernamePassword,
    implements<span style="color: black;">&#40;</span>ICredentialsChecker<span style="color: black;">&#41;</span>
&nbsp;
    <span style="color: #ff7700;font-weight:bold;">def</span> requestAvatarId<span style="color: black;">&#40;</span><span style="color: #008000;">self</span>, credentials<span style="color: black;">&#41;</span>:
        <span style="color: #ff7700;font-weight:bold;">if</span> pam.<span style="color: black;">authenticate</span><span style="color: black;">&#40;</span>credentials.<span style="color: black;">username</span>, credentials.<span style="color: black;">password</span><span style="color: black;">&#41;</span>:
            <span style="color: #ff7700;font-weight:bold;">return</span> defer.<span style="color: black;">succeed</span><span style="color: black;">&#40;</span>credentials.<span style="color: black;">username</span><span style="color: black;">&#41;</span>
        <span style="color: #ff7700;font-weight:bold;">return</span> defer.<span style="color: black;">fail</span><span style="color: black;">&#40;</span>UnauthorizedLogin<span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;invalid password&quot;</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
&nbsp;
&nbsp;
<span style="color: #ff7700;font-weight:bold;">class</span> UnixSSHdFactory<span style="color: black;">&#40;</span>factory.<span style="color: black;">SSHFactory</span><span style="color: black;">&#41;</span>:
    publicKeys = <span style="color: black;">&#123;</span>
        <span style="color: #483d8b;">'ssh-rsa'</span>: keys.<span style="color: black;">Key</span>.<span style="color: black;">fromString</span><span style="color: black;">&#40;</span>data=publicKey<span style="color: black;">&#41;</span>
    <span style="color: black;">&#125;</span>
    privateKeys = <span style="color: black;">&#123;</span>
        <span style="color: #483d8b;">'ssh-rsa'</span>: keys.<span style="color: black;">Key</span>.<span style="color: black;">fromString</span><span style="color: black;">&#40;</span>data=privateKey<span style="color: black;">&#41;</span>
    <span style="color: black;">&#125;</span>
    services = <span style="color: black;">&#123;</span>
        <span style="color: #483d8b;">'ssh-userauth'</span>: userauth.<span style="color: black;">SSHUserAuthServer</span>,
        <span style="color: #483d8b;">'ssh-connection'</span>: connection.<span style="color: black;">SSHConnection</span>
    <span style="color: black;">&#125;</span>
&nbsp;
<span style="color: #808080; font-style: italic;"># Components have already been registered in twisted.conch.unix</span>
&nbsp;
portal = portal.<span style="color: black;">Portal</span><span style="color: black;">&#40;</span>UnixSSHRealm<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
portal.<span style="color: black;">registerChecker</span><span style="color: black;">&#40;</span>PamPasswordDatabase<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>   <span style="color: #808080; font-style: italic;"># Supports PAM</span>
portal.<span style="color: black;">registerChecker</span><span style="color: black;">&#40;</span>SSHPublicKeyDatabase<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>  <span style="color: #808080; font-style: italic;"># Supports PKI</span>
UnixSSHdFactory.<span style="color: black;">portal</span> = portal
&nbsp;
<span style="color: #ff7700;font-weight:bold;">if</span> __name__ == <span style="color: #483d8b;">'__main__'</span>:
    reactor.<span style="color: black;">listenTCP</span><span style="color: black;">&#40;</span><span style="color: #ff4500;">5022</span>, UnixSSHdFactory<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
    reactor.<span style="color: black;">run</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span></pre></div></div>
<p>Some notes:</p>
<ul>
<li>The server uses the very same public and private keys as found in the <code>sshsimpleserver.py</code> script. Make sure you generate new keys using <strong>ssh-keygen</strong> if you plan to run this on a public server (although this not recommended).</li>
<li>Twisted included a module for PAM authentication, <code>twisted.cred.pamauth</code>, but unfortunately I could not locate one of its dependencies to make it work. So, I used the excellent <a href="http://atlee.ca/software/pam/">python-pam</a> to create a custom PAM authenticator class.</li>
<li>I can guess what you might thought when you read about this code:<br />
<blockquote>Python is a cross-platform programming language. Twisted runs on Windows. So, is this a solution for running a SSH server on Win32?</p></blockquote>
<p> Well, at the moment it won&#8217;t run because internally it uses some Python modules that are available on UNIX platforms only. But, I intend to investigate the possibility of running this on <strong>Windows</strong> since I already need something like that.</li>
</ul>
<p>We can now enjoy our Python SSH server. Run as root:</p>
<pre class="console">
python scripts/rapidsshd_unix.py
</pre>
<p>From another machine, connect to the server using an <em>ssh client</em>:</p>
<pre class="console">
ssh -p 5022 rocky@arena
</pre>
<p>If you have deployed your public key in the <code>~/.ssh/authorized_keys</code> file on the remote machine (<em>arena</em>), you should be able to authenticate using the public key:</p>
<pre class="console">
ssh -p 5022 -i /path/to/private.key rocky@arena
</pre>
<p>You should get output like the following on the server:</p>
<pre class="console">
[root@arena ~]# python ssh.py
2010-03-26 21:30:05+0000 [-] Log opened.
2010-03-26 21:30:05+0000 [-] __main__.UnixSSHdFactory starting on 5022
2010-03-26 21:30:05+0000 [-] Starting factory <__main__.UnixSSHdFactory instance at 0xb7a0b0cc>
2010-03-26 21:30:13+0000 [__main__.UnixSSHdFactory] disabling diffie-hellman-group-exchange because we cannot find moduli file
2010-03-26 21:30:13+0000 [SSHServerTransport,0,192.168.0.172] kex alg, key alg: diffie-hellman-group1-sha1 ssh-rsa
2010-03-26 21:30:13+0000 [SSHServerTransport,0,192.168.0.172] outgoing: aes256-ctr hmac-sha1 none
2010-03-26 21:30:13+0000 [SSHServerTransport,0,192.168.0.172] incoming: aes256-ctr hmac-sha1 none
2010-03-26 21:30:14+0000 [SSHServerTransport,0,192.168.0.172] NEW KEYS
2010-03-26 21:30:14+0000 [SSHServerTransport,0,192.168.0.172] starting service ssh-userauth
2010-03-26 21:30:17+0000 [SSHService ssh-userauth on SSHServerTransport,0,192.168.0.172] rocky trying auth none
2010-03-26 21:30:17+0000 [SSHService ssh-userauth on SSHServerTransport,0,192.168.0.172] rocky trying auth publickey
2010-03-26 21:30:17+0000 [SSHService ssh-userauth on SSHServerTransport,0,192.168.0.172] rocky trying auth publickey
2010-03-26 21:30:17+0000 [SSHService ssh-userauth on SSHServerTransport,0,192.168.0.172] rocky authenticated with publickey
2010-03-26 21:30:17+0000 [SSHService ssh-userauth on SSHServerTransport,0,192.168.0.172] starting service ssh-connection
2010-03-26 21:30:17+0000 [SSHService ssh-connection on SSHServerTransport,0,192.168.0.172] got channel session request
2010-03-26 21:30:17+0000 [SSHChannel session (0) on SSHService ssh-connection on SSHServerTransport,0,192.168.0.172] channel open
2010-03-26 21:30:17+0000 [SSHChannel session (0) on SSHService ssh-connection on SSHServerTransport,0,192.168.0.172] pty request: xterm (24L, 80L, 0L, 0L)
2010-03-26 21:30:17+0000 [SSHChannel session (0) on SSHService ssh-connection on SSHServerTransport,0,192.168.0.172] getting shell
</pre>
<p>This first release of the <a href="http://bitbucket.org/gnotaras/rapidssh/">RapidSSH</a> project exists solely for demonstration purposes. Don&#8217;t get fooled by the small amount of code. Information about how to put the pieces together is scarce and it required a lot trial&#038;error and source code reading. The above implementation contains none of the customizations I had in mind. These will be done as soon as I find some time to do so. Until then it will be nice to hear about your experiences or implementations you have worked on.</p>
<div class="cc-block"><em><a href="http://www.g-loaded.eu/2010/03/26/python-ssh-server-unix-twisted-conch/">Python SSH Server for UNIX Systems using Twisted.conch</a></em>, unless otherwise expressly stated, is licensed under a <a rel="license" href="http://creativecommons.org/licenses/by-nc-sa/3.0/">Creative Commons Attribution-Noncommercial-Share Alike 3.0 Unported License</a>. Terms and conditions beyond the scope of this license may be available at <a href="http://www.g-loaded.eu/about/disclaimer-and-license/">www.g-loaded.eu</a>.</div>
<h4>Related Articles</h4>
<ul><li><a href="http://www.g-loaded.eu/2006/09/23/use-python-to-get-the-web-page-data-in-epiphany/" rel="bookmark">Use Python to get the web page data in Epiphany</a></li>
<li><a href="http://www.g-loaded.eu/2006/05/17/epiphany-python-console-open-new-tab/" rel="bookmark">Epiphany Python Console &#8211; Open New Tab</a></li>
<li><a href="http://www.g-loaded.eu/2007/01/31/python-irc-bot/" rel="bookmark">Python IRC Bot</a></li>
<li><a href="http://www.g-loaded.eu/2006/04/07/python-crash-course/" rel="bookmark">Python Crash Course</a></li>
<li><a href="http://www.g-loaded.eu/2005/11/10/configure-vnc-server-in-fedora/" rel="bookmark">Set up the VNC Server in Fedora</a></li></ul>]]></content:encoded>
			<wfw:commentRss>http://www.g-loaded.eu/2010/03/26/python-ssh-server-unix-twisted-conch/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	<creativeCommons:license>http://creativecommons.org/licenses/by-nc-sa/3.0/</creativeCommons:license>
	</item>
		<item>
		<title>ping.py &#8211; Python Implementation of the ping command</title>
		<link>http://www.g-loaded.eu/2009/10/30/python-ping/</link>
		<comments>http://www.g-loaded.eu/2009/10/30/python-ping/#comments</comments>
		<pubDate>Fri, 30 Oct 2009 18:54:18 +0000</pubDate>
		<dc:creator>George Notaras</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[Networking]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[Snippet]]></category>
		<guid isPermaLink="false">http://www.g-loaded.eu/?p=1408</guid>
		<description><![CDATA[I&#8217;ve been looking for a pure python implementation of the ping command. Now that I found one, I am not sure if I want to use it, as it has a restriction: only privileged users can ping other hosts. I&#8217;ve used the ping command successfully as a normal user on all operating systems I have [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve been looking for a pure python implementation of the <strong>ping</strong> command. Now that I found one, I am not sure if I want to use it, as it has a <em>restriction</em>: only privileged users can ping other hosts. I&#8217;ve used the ping command successfully as a normal user on all operating systems I have tried and never had an issue. Currently, I do not have the time to investigate this limitation, but, judging by the exception I get, it has to do with the creation of the socket through which the ICMP packet is sent. The normal user does not have the required privileges to create this socket.</p>
<p>[This post has been updated]<br />
<span id="more-1408"></span><br />
[<strong>Update #1</strong>]: This limitation also exists on the <strong>ping</strong> command, which runs with <strong>setuid</strong> access rights. (Thanks <a href="http://www.sakana.fr/blog/">Stephane</a>)</p>
<p>[<strong>Update #2</strong>]: After <a href="http://cdhallman.blogspot.com">Chris Hallman</a> reported that the original code actually works on Windows only, I made some changes to it and publish the updated code below.</p>
<p>The following code is a pure <strong>Python</strong> implementation of the <strong>ping</strong> command. I originally found it in the <a href="http://trac.pylucid.net/browser/CodeSnippets/ping.py">source code tree of pylucid</a> in a subdirectory where the developers keep various code snippets.</p>
<p>I had originally tested the code under Microsoft Windows as this was the OS I had available at the moment.  Chris Hallman noticed that the code does not work under GNU/Linux. After spending some hours trying to figure out what was wrong it, I realized that the part of the code that caused the failure on Linux was the use of the <code>time.clock()</code> function instead of <code>time.time()</code>. The <code>clock()</code> method works <a href="http://docs.python.org/library/time.html#time.clock">differently</a> under Windows and Linux.</p>
<p>I fixed the 2007 implementation and hereby publish the updated code(as <a href="http://www.g-loaded.eu/2009/10/30/python-ping/">python-ping</a>). Feel free to test it and report any issues.</p>
<p>Needed: test on Solaris.</p>
<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #808080; font-style: italic;">#!/usr/bin/env python</span>
&nbsp;
<span style="color: #483d8b;">&quot;&quot;&quot;
    A pure python ping implementation using raw socket.
&nbsp;
&nbsp;
    Note that ICMP messages can only be sent from processes running as root.
&nbsp;
&nbsp;
    Derived from ping.c distributed in Linux's netkit. That code is
    copyright (c) 1989 by The Regents of the University of California.
    That code is in turn derived from code written by Mike Muuss of the
    US Army Ballistic Research Laboratory in December, 1983 and
    placed in the public domain. They have my thanks.
&nbsp;
    Bugs are naturally mine. I'd be glad to hear about them. There are
    certainly word - size dependenceies here.
&nbsp;
    Copyright (c) Matthew Dixon Cowles, &lt;http://www.visi.com/~mdc/&gt;.
    Distributable under the terms of the GNU General Public License
    version 2. Provided with no warranties of any sort.
&nbsp;
    Original Version from Matthew Dixon Cowles:
      -&gt; ftp://ftp.visi.com/users/mdc/ping.py
&nbsp;
    Rewrite by Jens Diemer:
      -&gt; http://www.python-forum.de/post-69122.html#69122
&nbsp;
    Rewrite by George Notaras:
      -&gt; http://www.g-loaded.eu/2009/10/30/python-ping/
&nbsp;
    Revision history
    ~~~~~~~~~~~~~~~~
&nbsp;
    November 8, 2009
    ----------------
    Improved compatibility with GNU/Linux systems.
&nbsp;
    Fixes by:
     * George Notaras -- http://www.g-loaded.eu
    Reported by:
     * Chris Hallman -- http://cdhallman.blogspot.com
&nbsp;
    Changes in this release:
     - Re-use time.time() instead of time.clock(). The 2007 implementation
       worked only under Microsoft Windows. Failed on GNU/Linux.
       time.clock() behaves differently under the two OSes[1].
&nbsp;
    [1] http://docs.python.org/library/time.html#time.clock
&nbsp;
    May 30, 2007
    ------------
    little rewrite by Jens Diemer:
     -  change socket asterisk import to a normal import
     -  replace time.time() with time.clock()
     -  delete &quot;return None&quot; (or change to &quot;return&quot; only)
     -  in checksum() rename &quot;str&quot; to &quot;source_string&quot;
&nbsp;
    November 22, 1997
    -----------------
    Initial hack. Doesn't do much, but rather than try to guess
    what features I (or others) will want in the future, I've only
    put in what I need now.
&nbsp;
    December 16, 1997
    -----------------
    For some reason, the checksum bytes are in the wrong order when
    this is run under Solaris 2.X for SPARC but it works right under
    Linux x86. Since I don't know just what's wrong, I'll swap the
    bytes always and then do an htons().
&nbsp;
    December 4, 2000
    ----------------
    Changed the struct.pack() calls to pack the checksum and ID as
    unsigned. My thanks to Jerome Poincheval for the fix.
&nbsp;
&nbsp;
    Last commit info:
    ~~~~~~~~~~~~~~~~~
    $LastChangedDate: $
    $Rev: $
    $Author: $
&quot;&quot;&quot;</span>
&nbsp;
&nbsp;
<span style="color: #ff7700;font-weight:bold;">import</span> <span style="color: #dc143c;">os</span>, <span style="color: #dc143c;">sys</span>, <span style="color: #dc143c;">socket</span>, <span style="color: #dc143c;">struct</span>, <span style="color: #dc143c;">select</span>, <span style="color: #dc143c;">time</span>
&nbsp;
<span style="color: #808080; font-style: italic;"># From /usr/include/linux/icmp.h; your milage may vary.</span>
ICMP_ECHO_REQUEST = <span style="color: #ff4500;">8</span> <span style="color: #808080; font-style: italic;"># Seems to be the same on Solaris.</span>
&nbsp;
&nbsp;
<span style="color: #ff7700;font-weight:bold;">def</span> checksum<span style="color: black;">&#40;</span>source_string<span style="color: black;">&#41;</span>:
    <span style="color: #483d8b;">&quot;&quot;&quot;
    I'm not too confident that this is right but testing seems
    to suggest that it gives the same answers as in_cksum in ping.c
    &quot;&quot;&quot;</span>
    <span style="color: #008000;">sum</span> = <span style="color: #ff4500;">0</span>
    countTo = <span style="color: black;">&#40;</span><span style="color: #008000;">len</span><span style="color: black;">&#40;</span>source_string<span style="color: black;">&#41;</span>/<span style="color: #ff4500;">2</span><span style="color: black;">&#41;</span><span style="color: #66cc66;">*</span><span style="color: #ff4500;">2</span>
    count = <span style="color: #ff4500;">0</span>
    <span style="color: #ff7700;font-weight:bold;">while</span> count<span style="color: #66cc66;">&lt;</span>countTo:
        thisVal = <span style="color: #008000;">ord</span><span style="color: black;">&#40;</span>source_string<span style="color: black;">&#91;</span>count + <span style="color: #ff4500;">1</span><span style="color: black;">&#93;</span><span style="color: black;">&#41;</span><span style="color: #66cc66;">*</span><span style="color: #ff4500;">256</span> + <span style="color: #008000;">ord</span><span style="color: black;">&#40;</span>source_string<span style="color: black;">&#91;</span>count<span style="color: black;">&#93;</span><span style="color: black;">&#41;</span>
        <span style="color: #008000;">sum</span> = <span style="color: #008000;">sum</span> + thisVal
        <span style="color: #008000;">sum</span> = <span style="color: #008000;">sum</span> <span style="color: #66cc66;">&amp;</span> 0xffffffff <span style="color: #808080; font-style: italic;"># Necessary?</span>
        count = count + <span style="color: #ff4500;">2</span>
&nbsp;
    <span style="color: #ff7700;font-weight:bold;">if</span> countTo<span style="color: #66cc66;">&lt;</span>len<span style="color: black;">&#40;</span>source_string<span style="color: black;">&#41;</span>:
        <span style="color: #008000;">sum</span> = <span style="color: #008000;">sum</span> + <span style="color: #008000;">ord</span><span style="color: black;">&#40;</span>source_string<span style="color: black;">&#91;</span><span style="color: #008000;">len</span><span style="color: black;">&#40;</span>source_string<span style="color: black;">&#41;</span> - <span style="color: #ff4500;">1</span><span style="color: black;">&#93;</span><span style="color: black;">&#41;</span>
        <span style="color: #008000;">sum</span> = <span style="color: #008000;">sum</span> <span style="color: #66cc66;">&amp;</span> 0xffffffff <span style="color: #808080; font-style: italic;"># Necessary?</span>
&nbsp;
    <span style="color: #008000;">sum</span> = <span style="color: black;">&#40;</span><span style="color: #008000;">sum</span> <span style="color: #66cc66;">&gt;&gt;</span> <span style="color: #ff4500;">16</span><span style="color: black;">&#41;</span>  +  <span style="color: black;">&#40;</span><span style="color: #008000;">sum</span> <span style="color: #66cc66;">&amp;</span> 0xffff<span style="color: black;">&#41;</span>
    <span style="color: #008000;">sum</span> = <span style="color: #008000;">sum</span> + <span style="color: black;">&#40;</span><span style="color: #008000;">sum</span> <span style="color: #66cc66;">&gt;&gt;</span> <span style="color: #ff4500;">16</span><span style="color: black;">&#41;</span>
    answer = ~<span style="color: #008000;">sum</span>
    answer = answer <span style="color: #66cc66;">&amp;</span> 0xffff
&nbsp;
    <span style="color: #808080; font-style: italic;"># Swap bytes. Bugger me if I know why.</span>
    answer = answer <span style="color: #66cc66;">&gt;&gt;</span> <span style="color: #ff4500;">8</span> | <span style="color: black;">&#40;</span>answer <span style="color: #66cc66;">&lt;&lt;</span> <span style="color: #ff4500;">8</span> <span style="color: #66cc66;">&amp;</span> 0xff00<span style="color: black;">&#41;</span>
&nbsp;
    <span style="color: #ff7700;font-weight:bold;">return</span> answer
&nbsp;
&nbsp;
<span style="color: #ff7700;font-weight:bold;">def</span> receive_one_ping<span style="color: black;">&#40;</span>my_socket, ID, timeout<span style="color: black;">&#41;</span>:
    <span style="color: #483d8b;">&quot;&quot;&quot;
    receive the ping from the socket.
    &quot;&quot;&quot;</span>
    timeLeft = timeout
    <span style="color: #ff7700;font-weight:bold;">while</span> <span style="color: #008000;">True</span>:
        startedSelect = <span style="color: #dc143c;">time</span>.<span style="color: #dc143c;">time</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
        whatReady = <span style="color: #dc143c;">select</span>.<span style="color: #dc143c;">select</span><span style="color: black;">&#40;</span><span style="color: black;">&#91;</span>my_socket<span style="color: black;">&#93;</span>, <span style="color: black;">&#91;</span><span style="color: black;">&#93;</span>, <span style="color: black;">&#91;</span><span style="color: black;">&#93;</span>, timeLeft<span style="color: black;">&#41;</span>
        howLongInSelect = <span style="color: black;">&#40;</span><span style="color: #dc143c;">time</span>.<span style="color: #dc143c;">time</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span> - startedSelect<span style="color: black;">&#41;</span>
        <span style="color: #ff7700;font-weight:bold;">if</span> whatReady<span style="color: black;">&#91;</span><span style="color: #ff4500;">0</span><span style="color: black;">&#93;</span> == <span style="color: black;">&#91;</span><span style="color: black;">&#93;</span>: <span style="color: #808080; font-style: italic;"># Timeout</span>
            <span style="color: #ff7700;font-weight:bold;">return</span>
&nbsp;
        timeReceived = <span style="color: #dc143c;">time</span>.<span style="color: #dc143c;">time</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
        recPacket, addr = my_socket.<span style="color: black;">recvfrom</span><span style="color: black;">&#40;</span><span style="color: #ff4500;">1024</span><span style="color: black;">&#41;</span>
        icmpHeader = recPacket<span style="color: black;">&#91;</span><span style="color: #ff4500;">20</span>:<span style="color: #ff4500;">28</span><span style="color: black;">&#93;</span>
        <span style="color: #008000;">type</span>, <span style="color: #dc143c;">code</span>, checksum, packetID, sequence = <span style="color: #dc143c;">struct</span>.<span style="color: black;">unpack</span><span style="color: black;">&#40;</span>
            <span style="color: #483d8b;">&quot;bbHHh&quot;</span>, icmpHeader
        <span style="color: black;">&#41;</span>
        <span style="color: #ff7700;font-weight:bold;">if</span> packetID == ID:
            bytesInDouble = <span style="color: #dc143c;">struct</span>.<span style="color: black;">calcsize</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;d&quot;</span><span style="color: black;">&#41;</span>
            timeSent = <span style="color: #dc143c;">struct</span>.<span style="color: black;">unpack</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;d&quot;</span>, recPacket<span style="color: black;">&#91;</span><span style="color: #ff4500;">28</span>:<span style="color: #ff4500;">28</span> + bytesInDouble<span style="color: black;">&#93;</span><span style="color: black;">&#41;</span><span style="color: black;">&#91;</span><span style="color: #ff4500;">0</span><span style="color: black;">&#93;</span>
            <span style="color: #ff7700;font-weight:bold;">return</span> timeReceived - timeSent
&nbsp;
        timeLeft = timeLeft - howLongInSelect
        <span style="color: #ff7700;font-weight:bold;">if</span> timeLeft <span style="color: #66cc66;">&lt;</span>= <span style="color: #ff4500;">0</span>:
            <span style="color: #ff7700;font-weight:bold;">return</span>
&nbsp;
&nbsp;
<span style="color: #ff7700;font-weight:bold;">def</span> send_one_ping<span style="color: black;">&#40;</span>my_socket, dest_addr, ID<span style="color: black;">&#41;</span>:
    <span style="color: #483d8b;">&quot;&quot;&quot;
    Send one ping to the given &gt;dest_addr&lt;.
    &quot;&quot;&quot;</span>
    dest_addr  =  <span style="color: #dc143c;">socket</span>.<span style="color: black;">gethostbyname</span><span style="color: black;">&#40;</span>dest_addr<span style="color: black;">&#41;</span>
&nbsp;
    <span style="color: #808080; font-style: italic;"># Header is type (8), code (8), checksum (16), id (16), sequence (16)</span>
    my_checksum = <span style="color: #ff4500;">0</span>
&nbsp;
    <span style="color: #808080; font-style: italic;"># Make a dummy heder with a 0 checksum.</span>
    header = <span style="color: #dc143c;">struct</span>.<span style="color: black;">pack</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;bbHHh&quot;</span>, ICMP_ECHO_REQUEST, <span style="color: #ff4500;">0</span>, my_checksum, ID, <span style="color: #ff4500;">1</span><span style="color: black;">&#41;</span>
    bytesInDouble = <span style="color: #dc143c;">struct</span>.<span style="color: black;">calcsize</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;d&quot;</span><span style="color: black;">&#41;</span>
    data = <span style="color: black;">&#40;</span><span style="color: #ff4500;">192</span> - bytesInDouble<span style="color: black;">&#41;</span> <span style="color: #66cc66;">*</span> <span style="color: #483d8b;">&quot;Q&quot;</span>
    data = <span style="color: #dc143c;">struct</span>.<span style="color: black;">pack</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;d&quot;</span>, <span style="color: #dc143c;">time</span>.<span style="color: #dc143c;">time</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span> + data
&nbsp;
    <span style="color: #808080; font-style: italic;"># Calculate the checksum on the data and the dummy header.</span>
    my_checksum = checksum<span style="color: black;">&#40;</span>header + data<span style="color: black;">&#41;</span>
&nbsp;
    <span style="color: #808080; font-style: italic;"># Now that we have the right checksum, we put that in. It's just easier</span>
    <span style="color: #808080; font-style: italic;"># to make up a new header than to stuff it into the dummy.</span>
    header = <span style="color: #dc143c;">struct</span>.<span style="color: black;">pack</span><span style="color: black;">&#40;</span>
        <span style="color: #483d8b;">&quot;bbHHh&quot;</span>, ICMP_ECHO_REQUEST, <span style="color: #ff4500;">0</span>, <span style="color: #dc143c;">socket</span>.<span style="color: black;">htons</span><span style="color: black;">&#40;</span>my_checksum<span style="color: black;">&#41;</span>, ID, <span style="color: #ff4500;">1</span>
    <span style="color: black;">&#41;</span>
    packet = header + data
    my_socket.<span style="color: black;">sendto</span><span style="color: black;">&#40;</span>packet, <span style="color: black;">&#40;</span>dest_addr, <span style="color: #ff4500;">1</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span> <span style="color: #808080; font-style: italic;"># Don't know about the 1</span>
&nbsp;
&nbsp;
<span style="color: #ff7700;font-weight:bold;">def</span> do_one<span style="color: black;">&#40;</span>dest_addr, timeout<span style="color: black;">&#41;</span>:
    <span style="color: #483d8b;">&quot;&quot;&quot;
    Returns either the delay (in seconds) or none on timeout.
    &quot;&quot;&quot;</span>
    icmp = <span style="color: #dc143c;">socket</span>.<span style="color: black;">getprotobyname</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;icmp&quot;</span><span style="color: black;">&#41;</span>
    <span style="color: #ff7700;font-weight:bold;">try</span>:
        my_socket = <span style="color: #dc143c;">socket</span>.<span style="color: #dc143c;">socket</span><span style="color: black;">&#40;</span><span style="color: #dc143c;">socket</span>.<span style="color: black;">AF_INET</span>, <span style="color: #dc143c;">socket</span>.<span style="color: black;">SOCK_RAW</span>, icmp<span style="color: black;">&#41;</span>
    <span style="color: #ff7700;font-weight:bold;">except</span> <span style="color: #dc143c;">socket</span>.<span style="color: black;">error</span>, <span style="color: black;">&#40;</span><span style="color: #dc143c;">errno</span>, msg<span style="color: black;">&#41;</span>:
        <span style="color: #ff7700;font-weight:bold;">if</span> <span style="color: #dc143c;">errno</span> == <span style="color: #ff4500;">1</span>:
            <span style="color: #808080; font-style: italic;"># Operation not permitted</span>
            msg = msg + <span style="color: black;">&#40;</span>
                <span style="color: #483d8b;">&quot; - Note that ICMP messages can only be sent from processes&quot;</span>
                <span style="color: #483d8b;">&quot; running as root.&quot;</span>
            <span style="color: black;">&#41;</span>
            <span style="color: #ff7700;font-weight:bold;">raise</span> <span style="color: #dc143c;">socket</span>.<span style="color: black;">error</span><span style="color: black;">&#40;</span>msg<span style="color: black;">&#41;</span>
        <span style="color: #ff7700;font-weight:bold;">raise</span> <span style="color: #808080; font-style: italic;"># raise the original error</span>
&nbsp;
    my_ID = <span style="color: #dc143c;">os</span>.<span style="color: black;">getpid</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span> <span style="color: #66cc66;">&amp;</span> 0xFFFF
&nbsp;
    send_one_ping<span style="color: black;">&#40;</span>my_socket, dest_addr, my_ID<span style="color: black;">&#41;</span>
    delay = receive_one_ping<span style="color: black;">&#40;</span>my_socket, my_ID, timeout<span style="color: black;">&#41;</span>
&nbsp;
    my_socket.<span style="color: black;">close</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
    <span style="color: #ff7700;font-weight:bold;">return</span> delay
&nbsp;
&nbsp;
<span style="color: #ff7700;font-weight:bold;">def</span> verbose_ping<span style="color: black;">&#40;</span>dest_addr, timeout = <span style="color: #ff4500;">2</span>, count = <span style="color: #ff4500;">4</span><span style="color: black;">&#41;</span>:
    <span style="color: #483d8b;">&quot;&quot;&quot;
    Send &gt;count&lt; ping to &gt;dest_addr&lt; with the given &gt;timeout&lt; and display
    the result.
    &quot;&quot;&quot;</span>
    <span style="color: #ff7700;font-weight:bold;">for</span> i <span style="color: #ff7700;font-weight:bold;">in</span> <span style="color: #008000;">xrange</span><span style="color: black;">&#40;</span>count<span style="color: black;">&#41;</span>:
        <span style="color: #ff7700;font-weight:bold;">print</span> <span style="color: #483d8b;">&quot;ping %s...&quot;</span> <span style="color: #66cc66;">%</span> dest_addr,
        <span style="color: #ff7700;font-weight:bold;">try</span>:
            delay  =  do_one<span style="color: black;">&#40;</span>dest_addr, timeout<span style="color: black;">&#41;</span>
        <span style="color: #ff7700;font-weight:bold;">except</span> <span style="color: #dc143c;">socket</span>.<span style="color: black;">gaierror</span>, e:
            <span style="color: #ff7700;font-weight:bold;">print</span> <span style="color: #483d8b;">&quot;failed. (socket error: '%s')&quot;</span> <span style="color: #66cc66;">%</span> e<span style="color: black;">&#91;</span><span style="color: #ff4500;">1</span><span style="color: black;">&#93;</span>
            <span style="color: #ff7700;font-weight:bold;">break</span>
&nbsp;
        <span style="color: #ff7700;font-weight:bold;">if</span> delay  ==  <span style="color: #008000;">None</span>:
            <span style="color: #ff7700;font-weight:bold;">print</span> <span style="color: #483d8b;">&quot;failed. (timeout within %ssec.)&quot;</span> <span style="color: #66cc66;">%</span> timeout
        <span style="color: #ff7700;font-weight:bold;">else</span>:
            delay  =  delay <span style="color: #66cc66;">*</span> <span style="color: #ff4500;">1000</span>
            <span style="color: #ff7700;font-weight:bold;">print</span> <span style="color: #483d8b;">&quot;get ping in %0.4fms&quot;</span> <span style="color: #66cc66;">%</span> delay
    <span style="color: #ff7700;font-weight:bold;">print</span>
&nbsp;
&nbsp;
<span style="color: #ff7700;font-weight:bold;">if</span> __name__ == <span style="color: #483d8b;">'__main__'</span>:
    verbose_ping<span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;heise.de&quot;</span><span style="color: black;">&#41;</span>
    verbose_ping<span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;google.com&quot;</span><span style="color: black;">&#41;</span>
    verbose_ping<span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;a-test-url-taht-is-not-available.com&quot;</span><span style="color: black;">&#41;</span>
    verbose_ping<span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;192.168.1.1&quot;</span><span style="color: black;">&#41;</span></pre></div></div>
<p>I decided not to publish the updated code on <a href="http://www.codetrax.org">CodeTRAX</a>, where I normally publish any programming-related stuff, but leave it on <a href="http://www.g-loaded.eu">G-Loaded</a> instead.</p>
<div class="cc-block"><em><a href="http://www.g-loaded.eu/2009/10/30/python-ping/">ping.py &#8211; Python Implementation of the ping command</a></em>, unless otherwise expressly stated, is licensed under a <a rel="license" href="http://creativecommons.org/licenses/by-nc-sa/3.0/">Creative Commons Attribution-Noncommercial-Share Alike 3.0 Unported License</a>. Terms and conditions beyond the scope of this license may be available at <a href="http://www.g-loaded.eu/about/disclaimer-and-license/">www.g-loaded.eu</a>.</div>
<h4>Related Articles</h4>
<ul><li><a href="http://www.g-loaded.eu/2006/05/06/sockets-programming-in-python/" rel="bookmark">Sockets Programming In Python</a></li>
<li><a href="http://www.g-loaded.eu/2009/05/07/descramble-passwords-from-gftp-bookmarks-using-python/" rel="bookmark">Descramble Passwords from gftp Bookmarks using Python</a></li>
<li><a href="http://www.g-loaded.eu/2007/01/31/python-irc-bot/" rel="bookmark">Python IRC Bot</a></li>
<li><a href="http://www.g-loaded.eu/2006/09/23/use-python-to-get-the-web-page-data-in-epiphany/" rel="bookmark">Use Python to get the web page data in Epiphany</a></li>
<li><a href="http://www.g-loaded.eu/2006/04/07/python-crash-course/" rel="bookmark">Python Crash Course</a></li></ul>]]></content:encoded>
			<wfw:commentRss>http://www.g-loaded.eu/2009/10/30/python-ping/feed/</wfw:commentRss>
		<slash:comments>42</slash:comments>
	<creativeCommons:license>http://creativecommons.org/licenses/by-nc-sa/3.0/</creativeCommons:license>
	</item>
		<item>
		<title>Descramble Passwords from gftp Bookmarks using Python</title>
		<link>http://www.g-loaded.eu/2009/05/07/descramble-passwords-from-gftp-bookmarks-using-python/</link>
		<comments>http://www.g-loaded.eu/2009/05/07/descramble-passwords-from-gftp-bookmarks-using-python/#comments</comments>
		<pubDate>Thu, 07 May 2009 07:21:56 +0000</pubDate>
		<dc:creator>George Notaras</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[C]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[Snippet]]></category>
		<guid isPermaLink="false">http://www.g-loaded.eu/?p=1119</guid>
		<description><![CDATA[If you check the file where gftp keeps its bookmarks, you will notice that passwords are not stored in clear text. Instead, gftp has used an algorithm to scramble them. I cannot recall if it was one or two years ago when I had decided to write a script to convert the bookmarks from the [...]]]></description>
			<content:encoded><![CDATA[<p>If you check the file where <a href="http://gftp.seul.org/">gftp</a> keeps its bookmarks, you will notice that passwords are not stored in <em>clear text</em>. Instead, gftp has used an algorithm to <em>scramble</em> them. I cannot recall if it was one or two years ago when I had decided to write a script to convert the bookmarks from the gftp format to the FileZilla format, but I do recall that I had to descramble the passwords from the gftp bookmarks and the C code of that password descrambling algorithm had given me a hard time, because I had to port it to Python, since Python was the programming language I intended to use for my bookmark converter. At that time, I happened to hang out at <em>#python</em>, so I had asked for some help there and a kind fellow pythonista had saved the day.<br />
<span id="more-1119"></span><br />
The <strong>original password descrambling algorithm</strong> in C as found in the gftp sources at that time (<em>gftp-2.0.18/lib/misc.c</em>):</p>
<div class="wp_syntax"><div class="code"><pre class="c" style="font-family:monospace;">&nbsp;
<span style="color: #993333;">char</span> <span style="color: #339933;">*</span>
gftp_descramble_password <span style="color: #009900;">&#40;</span><span style="color: #993333;">const</span> <span style="color: #993333;">char</span> <span style="color: #339933;">*</span>password<span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#123;</span>
  <span style="color: #993333;">const</span> <span style="color: #993333;">char</span> <span style="color: #339933;">*</span>passwordpos<span style="color: #339933;">;</span>
  <span style="color: #993333;">char</span> <span style="color: #339933;">*</span>newstr<span style="color: #339933;">,</span> <span style="color: #339933;">*</span>newpos<span style="color: #339933;">;</span>
  <span style="color: #993333;">int</span> error<span style="color: #339933;">;</span>
&nbsp;
  <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #339933;">*</span>password <span style="color: #339933;">!=</span> <span style="color: #ff0000;">'$'</span><span style="color: #009900;">&#41;</span>
    <span style="color: #b1b100;">return</span> <span style="color: #009900;">&#40;</span>g_strdup <span style="color: #009900;">&#40;</span>password<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
  passwordpos <span style="color: #339933;">=</span> password <span style="color: #339933;">+</span> <span style="color: #0000dd;">1</span><span style="color: #339933;">;</span>
  newstr <span style="color: #339933;">=</span> g_malloc <span style="color: #009900;">&#40;</span>strlen <span style="color: #009900;">&#40;</span>passwordpos<span style="color: #009900;">&#41;</span> <span style="color: #339933;">/</span> <span style="color: #0000dd;">2</span> <span style="color: #339933;">+</span> <span style="color: #0000dd;">1</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  newpos <span style="color: #339933;">=</span> newstr<span style="color: #339933;">;</span>
&nbsp;
  error <span style="color: #339933;">=</span> <span style="color: #0000dd;">0</span><span style="color: #339933;">;</span>
  <span style="color: #b1b100;">while</span> <span style="color: #009900;">&#40;</span><span style="color: #339933;">*</span>passwordpos <span style="color: #339933;">!=</span> <span style="color: #ff0000;">'<span style="color: #006699; font-weight: bold;">\0</span>'</span> <span style="color: #339933;">&amp;&amp;</span> <span style="color: #009900;">&#40;</span><span style="color: #339933;">*</span>passwordpos <span style="color: #339933;">+</span> <span style="color: #0000dd;">1</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">!=</span> <span style="color: #ff0000;">'<span style="color: #006699; font-weight: bold;">\0</span>'</span><span style="color: #009900;">&#41;</span>
    <span style="color: #009900;">&#123;</span>
      <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #009900;">&#40;</span><span style="color: #339933;">*</span>passwordpos <span style="color: #339933;">&amp;</span> <span style="color: #208080;">0xc3</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">!=</span> <span style="color: #208080;">0x41</span> <span style="color: #339933;">||</span>
          <span style="color: #009900;">&#40;</span><span style="color: #339933;">*</span><span style="color: #009900;">&#40;</span>passwordpos <span style="color: #339933;">+</span> <span style="color: #0000dd;">1</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">&amp;</span> <span style="color: #208080;">0xc3</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">!=</span> <span style="color: #208080;">0x41</span><span style="color: #009900;">&#41;</span>
        <span style="color: #009900;">&#123;</span>
          error <span style="color: #339933;">=</span> <span style="color: #0000dd;">1</span><span style="color: #339933;">;</span>
          <span style="color: #000000; font-weight: bold;">break</span><span style="color: #339933;">;</span>
        <span style="color: #009900;">&#125;</span>
&nbsp;
      <span style="color: #339933;">*</span>newpos<span style="color: #339933;">++</span> <span style="color: #339933;">=</span> <span style="color: #009900;">&#40;</span><span style="color: #009900;">&#40;</span><span style="color: #339933;">*</span>passwordpos <span style="color: #339933;">&amp;</span> <span style="color: #208080;">0x3c</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">&lt;&lt;</span> <span style="color: #0000dd;">2</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">|</span>
                  <span style="color: #009900;">&#40;</span><span style="color: #009900;">&#40;</span><span style="color: #339933;">*</span><span style="color: #009900;">&#40;</span>passwordpos <span style="color: #339933;">+</span> <span style="color: #0000dd;">1</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">&amp;</span> <span style="color: #208080;">0x3c</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">&gt;&gt;</span> <span style="color: #0000dd;">2</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
      passwordpos <span style="color: #339933;">+=</span> <span style="color: #0000dd;">2</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
  <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span>error<span style="color: #009900;">&#41;</span>
    <span style="color: #009900;">&#123;</span>
      g_free <span style="color: #009900;">&#40;</span>newstr<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
      <span style="color: #b1b100;">return</span> <span style="color: #009900;">&#40;</span>g_strdup <span style="color: #009900;">&#40;</span>password<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
  <span style="color: #339933;">*</span>newpos <span style="color: #339933;">=</span> <span style="color: #ff0000;">'<span style="color: #006699; font-weight: bold;">\0</span>'</span><span style="color: #339933;">;</span>
  <span style="color: #b1b100;">return</span> <span style="color: #009900;">&#40;</span>newstr<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>
<p>The following is the Python port of the above code. The person who did the porting wished to remain nameless. The exact answer I got when I had asked about how I should give him credit for the code was:</p>
<blockquote><p>
please don&#8217;t attach my name to it. it&#8217;s horrible, awful code. Consider it public domain, do with it as you wish.
</p></blockquote>
<p>Python port:</p>
<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;">&nbsp;
<span style="color: #ff7700;font-weight:bold;">def</span> gftp_descrable_password<span style="color: black;">&#40;</span>password<span style="color: black;">&#41;</span>:
    <span style="color: #483d8b;">&quot;&quot;&quot;gftp password descrambler
&nbsp;
    This code has been released in the Public Domain by the original author.
&nbsp;
    &quot;&quot;&quot;</span>
    <span style="color: #ff7700;font-weight:bold;">if</span> <span style="color: #ff7700;font-weight:bold;">not</span> password.<span style="color: black;">startswith</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'$'</span><span style="color: black;">&#41;</span>:
        <span style="color: #ff7700;font-weight:bold;">return</span> password
    newpassword = <span style="color: black;">&#91;</span><span style="color: black;">&#93;</span>
    pwdparts = <span style="color: #008000;">map</span><span style="color: black;">&#40;</span><span style="color: #008000;">ord</span>, password<span style="color: black;">&#41;</span>
    <span style="color: #ff7700;font-weight:bold;">for</span> i <span style="color: #ff7700;font-weight:bold;">in</span> <span style="color: #008000;">range</span><span style="color: black;">&#40;</span><span style="color: #ff4500;">1</span>, <span style="color: #008000;">len</span><span style="color: black;">&#40;</span>pwdparts<span style="color: black;">&#41;</span>, <span style="color: #ff4500;">2</span><span style="color: black;">&#41;</span>:
        <span style="color: #ff7700;font-weight:bold;">if</span> <span style="color: black;">&#40;</span><span style="color: black;">&#40;</span>pwdparts<span style="color: black;">&#91;</span>i<span style="color: black;">&#93;</span> <span style="color: #66cc66;">&amp;</span> 0xc3<span style="color: black;">&#41;</span> <span style="color: #66cc66;">!</span>= 0x41 <span style="color: #ff7700;font-weight:bold;">or</span>
            <span style="color: black;">&#40;</span>pwdparts<span style="color: black;">&#91;</span>i+<span style="color: #ff4500;">1</span><span style="color: black;">&#93;</span> <span style="color: #66cc66;">&amp;</span> 0xc3<span style="color: black;">&#41;</span> <span style="color: #66cc66;">!</span>= 0x41<span style="color: black;">&#41;</span>:
            <span style="color: #ff7700;font-weight:bold;">return</span> password
        newpassword.<span style="color: black;">append</span><span style="color: black;">&#40;</span><span style="color: #008000;">chr</span><span style="color: black;">&#40;</span><span style="color: black;">&#40;</span><span style="color: black;">&#40;</span>pwdparts<span style="color: black;">&#91;</span>i<span style="color: black;">&#93;</span> <span style="color: #66cc66;">&amp;</span> 0x3c<span style="color: black;">&#41;</span> <span style="color: #66cc66;">&lt;&lt;</span> <span style="color: #ff4500;">2</span><span style="color: black;">&#41;</span> +
                               <span style="color: black;">&#40;</span><span style="color: black;">&#40;</span>pwdparts<span style="color: black;">&#91;</span>i+<span style="color: #ff4500;">1</span><span style="color: black;">&#93;</span> <span style="color: #66cc66;">&amp;</span> 0x3c<span style="color: black;">&#41;</span> <span style="color: #66cc66;">&gt;&gt;</span> <span style="color: #ff4500;">2</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
    <span style="color: #ff7700;font-weight:bold;">return</span> <span style="color: #483d8b;">&quot;&quot;</span>.<span style="color: black;">join</span><span style="color: black;">&#40;</span>newpassword<span style="color: black;">&#41;</span></pre></div></div>
<p>The only thing I have added to the above code is the <em>docstring</em> so that the function can be reused without licensing issues.</p>
<p>The above snippet has not been thoroughly tested, but it seems to work fine.</p>
<p>As for the bookmark converter, I am not interested in doing it any more.</p>
<div class="cc-block"><em><a href="http://www.g-loaded.eu/2009/05/07/descramble-passwords-from-gftp-bookmarks-using-python/">Descramble Passwords from gftp Bookmarks using Python</a></em>, unless otherwise expressly stated, is licensed under a <a rel="license" href="http://creativecommons.org/licenses/by-nc-sa/3.0/">Creative Commons Attribution-Noncommercial-Share Alike 3.0 Unported License</a>. Terms and conditions beyond the scope of this license may be available at <a href="http://www.g-loaded.eu/about/disclaimer-and-license/">www.g-loaded.eu</a>.</div>
<h4>Related Articles</h4>
<ul><li><a href="http://www.g-loaded.eu/2007/05/11/smart-bookmarks-in-epiphany/" rel="bookmark">Smart Bookmarks in Epiphany</a></li>
<li><a href="http://www.g-loaded.eu/2010/03/26/python-ssh-server-unix-twisted-conch/" rel="bookmark">Python SSH Server for UNIX Systems using Twisted.conch</a></li>
<li><a href="http://www.g-loaded.eu/2009/10/30/python-ping/" rel="bookmark">ping.py &#8211; Python Implementation of the ping command</a></li>
<li><a href="http://www.g-loaded.eu/2006/04/07/python-crash-course/" rel="bookmark">Python Crash Course</a></li>
<li><a href="http://www.g-loaded.eu/2006/05/06/sockets-programming-in-python/" rel="bookmark">Sockets Programming In Python</a></li></ul>]]></content:encoded>
			<wfw:commentRss>http://www.g-loaded.eu/2009/05/07/descramble-passwords-from-gftp-bookmarks-using-python/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
	<creativeCommons:license>http://creativecommons.org/licenses/by-nc-sa/3.0/</creativeCommons:license>
	</item>
		<item>
		<title>Using the mod_dav_svn SVNParentPath directive with multiple authz files</title>
		<link>http://www.g-loaded.eu/2008/12/18/using-the-mod_dav_svn-svnparentpath-directive-with-multiple-authz-files/</link>
		<comments>http://www.g-loaded.eu/2008/12/18/using-the-mod_dav_svn-svnparentpath-directive-with-multiple-authz-files/#comments</comments>
		<pubDate>Thu, 18 Dec 2008 03:02:50 +0000</pubDate>
		<dc:creator>George Notaras</dc:creator>
				<category><![CDATA[Computers]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[Security]]></category>
		<category><![CDATA[Servers]]></category>
		<category><![CDATA[Subversion]]></category>
		<guid isPermaLink="false">http://www.g-loaded.eu/?p=805</guid>
		<description><![CDATA[I&#8217;ve been using the mod_dav_svn module for Apache, part of the subversion distribution package, in order to make several SVN repositories available over the HTTP protocol for quite some time now. More specifically, I use a multi-repository setup under the same virtualhost by using the SVNParentPath directive of mod_dav_svn. Also, the authorization policy is enforced [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve been using the <strong>mod_dav_svn</strong> module for <a href="http://httpd.apache.org/">Apache</a>, part of the <a href="http://subversion.tigris.org/">subversion</a> distribution package, in order to make several <em>SVN repositories</em> available over the HTTP protocol for quite some time now. More specifically, I use a <em>multi-repository</em> setup under the same virtualhost by using the <code>SVNParentPath</code> directive of <em>mod_dav_svn</em>. Also, the <strong>authorization policy</strong> is enforced by <strong>mod_authz_svn</strong> by using one general <em>authz</em> file (<code>AuthzSVNAccessFile</code>) containing the <em>policy rules</em>. In case the user is not authorized to access the resource, basic HTTP authentication is used to finally grant or deny access to the user. Everything works as expected, but let&#8217;s see if this is practical too&#8230;<br />
<span id="more-805"></span><br />
It is obvious that using such a setup, all <a href="http://subversion.tigris.org/">subversion</a> repositories share the same authz file. This is fine in most circumstances, but it presumes that one person or a small team of administrators will practically be able to manage the authorization policy inside the authz file, unless you grant read/write access to everyone, which is not very likely. And this is where problems begin to arise. What happens if there are 1000 development teams and thousands of requests to the admin team asking for modifications on the authz file? This is almost chaos. On the other hand, suppose that each SVN repository belongs to a development team which wishes to manage its repo&#8217;s authorization policy itself. What can be done in such a case? Unfortunately, nothing that will not require some coding. mod_authz_svn cannot handle multiple authorization files when a multi-repository configuration (<code>SVNParentPath</code>) is used.</p>
<p>One way to resolve the issue mentioned above is to inject our own authorization code into the relevant phase of the HTTP request processing. What this authorization code is going to do is to dynamically construct the path to the requested repository&#8217;s authz file, parse the authz file, determine the level of access the user may get in accordance to the HTTP request type and, finally, return an OK or an error code back to Apache.</p>
<p>Tonight I&#8217;ve spent several hours on this. Although, the appropriate approach would be to patch mod_authz_svn, I am not that excited about such an approach as I would need several days of hard work to modify an existing apache module. Instead, I have almost finished an <strong>authorization handler</strong> and an <strong>authz file parser</strong> (only basic syntax is supported), both written in python, which can be used by apache with the help of <a href="http://www.modpython.org/">mod_python</a>.</p>
<p>This is not finished yet. As you might have assumed I need this piece of code for <a href="http://www.codetrax.org/projects/project-codetrax">Project CodeTRAX</a>. Although, I had decided not to release anything related to that project until it is finished, I might make an exception and release this piece of python code in order to get some valuable feedback about if and how secure it is.</p>
<div class="cc-block"><em><a href="http://www.g-loaded.eu/2008/12/18/using-the-mod_dav_svn-svnparentpath-directive-with-multiple-authz-files/">Using the mod_dav_svn SVNParentPath directive with multiple authz files</a></em>, unless otherwise expressly stated, is licensed under a <a rel="license" href="http://creativecommons.org/licenses/by-nc-sa/3.0/">Creative Commons Attribution-Noncommercial-Share Alike 3.0 Unported License</a>. Terms and conditions beyond the scope of this license may be available at <a href="http://www.g-loaded.eu/about/disclaimer-and-license/">www.g-loaded.eu</a>.</div>
<h4>Related Articles</h4>
<ul><li><a href="http://www.g-loaded.eu/2009/10/05/strange-mod_dav_svn-error/" rel="bookmark">Strange mod_dav_svn error</a></li>
<li><a href="http://www.g-loaded.eu/2005/10/03/search-a-string-in-multiple-files/" rel="bookmark">Search for a string in multiple files</a></li>
<li><a href="http://www.g-loaded.eu/2010/04/12/a-change-of-plans-regarding-a-web-based-vcs-manager/" rel="bookmark">A change of plans regarding a web-based VCS manager</a></li>
<li><a href="http://www.g-loaded.eu/2007/12/01/veritar-verify-checksums-of-files-within-a-tar-archive/" rel="bookmark">VeriTAR &#8211; Verify checksums of files within a TAR archive</a></li>
<li><a href="http://www.g-loaded.eu/2010/10/04/rsapiget-download-rapidshare-api/" rel="bookmark">rsapiget downloads files using the new Rapidshare API</a></li></ul>]]></content:encoded>
			<wfw:commentRss>http://www.g-loaded.eu/2008/12/18/using-the-mod_dav_svn-svnparentpath-directive-with-multiple-authz-files/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	<creativeCommons:license>http://creativecommons.org/licenses/by-nc-sa/3.0/</creativeCommons:license>
	</item>
		<item>
		<title>Maximum URL Length</title>
		<link>http://www.g-loaded.eu/2008/10/24/maximum-url-length/</link>
		<comments>http://www.g-loaded.eu/2008/10/24/maximum-url-length/#comments</comments>
		<pubDate>Fri, 24 Oct 2008 10:07:12 +0000</pubDate>
		<dc:creator>George Notaras</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[HTTP]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[Specification]]></category>
		<guid isPermaLink="false">http://www.g-loaded.eu/?p=558</guid>
		<description><![CDATA[Normally, such pieces of information as the maximum length of a URL are completely useless. The developers of HTTP server and client software take good care of such details, so that they do not interfere with the user&#8217;s browsing experience. Yesterday, while trying to create a CGI version of a script, I realized that the [...]]]></description>
			<content:encoded><![CDATA[<p>Normally, such pieces of information as the maximum length of a <abbr title="Uniform Resource Locator">URL</abbr> are completely useless. The developers of HTTP server and client software take good care of such details, so that they do not interfere with the user&#8217;s browsing experience. Yesterday, while trying to create a <strong>CGI</strong> version of a script, I realized that the URL, which was produced by a <strong>GET</strong> HTTP request, was too lengthy, so I did some research about what is the maximum amount of characters a URL can contain.<br />
<span id="more-558"></span><br />
It turned out that only <a href="http://www.microsoft.com/windows/products/winfamily/ie/default.mspx">Internet Explorer</a> (up to version 7.0) has a limit. According to a <a href="http://support.microsoft.com/kb/208427">document</a> on Microsoft&#8217;s help and support site, <abbr title="Internet Explorer">IE</abbr> may accept a URL of <strong>2083</strong> characters max. Moreover, the <strong>path</strong> (that is www.example.org<strong>/this/is/the/path</strong>) may have a length of <strong>2048</strong> characters. As far as other browsers are concerned (<a href="http://www.mozilla.com/">Firefox</a>, <a href="http://www.apple.com/safari/">Safari</a>, <a href="http://www.opera.com/">Opera</a>), they <strong>practically</strong> have no <em>limits</em> in the URL length. <strong>Web servers</strong>, however, do have such limits, but this is normal for a server.</p>
<p>The <a href="http://en.wikipedia.org/wiki/HTTP">HTTP Protocol</a> <a href="http://www.w3.org/Protocols/rfc2616/rfc2616.html">specification</a> does not specify a maximum URL or path length, so the implementation of such limits is left to the developers of HTTP software.</p>
<p>The limits described above do not apply to <strong>POST HTTP requests</strong>. The data of such requests is completely contained into their <em>body</em> and not in the <em>headers</em>, therefore it is very unlikely that the <em>Host</em> header or the <em>path</em> exceed even Internet Explorer&#8217;s limits. Note that, if you do not use a HTML form or a high-level API <em>to generate the POST request</em>, it is required that you set the <strong>Content-Type</strong> header to be <em>application/x-www-form-urlencoded</em>. You can <a href="http://www.g-loaded.eu/2006/10/06/check-server-http-headers-with-curl/">check HTTP headers using curl</a>.</p>
<p>Below, you will find the headers and the body of an example POST request:</p>
<pre class="codesnp">
POST /cgi-bin/test.cgi HTTP/1.1
Host: www.example.org
Content-Type: application/x-www-form-urlencoded
Content-Length: 41
lastname=Smith&#038;firstname=John&#038;phone=12345
</pre>
<p>In <a href="http://python.org/">Python</a>, you can generate such a urlencoded body in the following way:</p>
<pre class="codesnp">
>>> param = { 'firstname':'John', 'lastname':'Smith', 'phone':'12345' }
>>> import urllib
>>> print urllib.urlencode(param)
lastname=Smith&#038;firstname=John&#038;phone=12345
</pre>
<p>This is exactly the same as generating the data of a <strong>GET</strong> request, but without any restrictions regarding the length, which is explicitly stated in the <em>Content-Length</em> header. Of course, you can use any programming language you like. This was just an example.</p>
<div class="cc-block"><em><a href="http://www.g-loaded.eu/2008/10/24/maximum-url-length/">Maximum URL Length</a></em>, unless otherwise expressly stated, is licensed under a <a rel="license" href="http://creativecommons.org/licenses/by-nc-sa/3.0/">Creative Commons Attribution-Noncommercial-Share Alike 3.0 Unported License</a>. Terms and conditions beyond the scope of this license may be available at <a href="http://www.g-loaded.eu/about/disclaimer-and-license/">www.g-loaded.eu</a>.</div>
<h4>Related Articles</h4>
<ul><li><a href="http://www.g-loaded.eu/2005/10/13/http-headers/" rel="bookmark">HTTP headers</a></li>
<li><a href="http://www.g-loaded.eu/2006/04/07/http-status-codes/" rel="bookmark">HTTP Status Codes</a></li>
<li><a href="http://www.g-loaded.eu/2006/08/24/modsecurity-overview/" rel="bookmark">ModSecurity Overview</a></li></ul>]]></content:encoded>
			<wfw:commentRss>http://www.g-loaded.eu/2008/10/24/maximum-url-length/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
	<creativeCommons:license>http://creativecommons.org/licenses/by-nc-sa/3.0/</creativeCommons:license>
	</item>
		<item>
		<title>VeriTAR &#8211; Verify checksums of files within a TAR archive</title>
		<link>http://www.g-loaded.eu/2007/12/01/veritar-verify-checksums-of-files-within-a-tar-archive/</link>
		<comments>http://www.g-loaded.eu/2007/12/01/veritar-verify-checksums-of-files-within-a-tar-archive/#comments</comments>
		<pubDate>Sat, 01 Dec 2007 14:24:44 +0000</pubDate>
		<dc:creator>George Notaras</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[Backup]]></category>
		<category><![CDATA[Filesystem]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[Software]]></category>
		<category><![CDATA[TAR]]></category>
		<category><![CDATA[Verification]]></category>
		<guid isPermaLink="false">http://www.g-loaded.eu/2007/12/01/veritar-verify-checksums-of-files-within-a-tar-archive/</guid>
		<description><![CDATA[In my opinion, the biggest problem of the tar format (&#8216;ustar&#8216;) is that it does not store the checksums of the files it contains. So, in order to be able to verify the contents of the tar archive, you either need to keep the original data on the hard drive and compare the archive contents [...]]]></description>
			<content:encoded><![CDATA[<p>In my opinion, the biggest problem of the <a href="http://en.wikipedia.org/wiki/Tar_(file_format)#USTAR_format">tar format</a> (&#8216;<em>ustar</em>&#8216;) is that it does not store the checksums of the files it contains. So, in order to be able to verify the contents of the tar archive, you either need to keep the original data on the hard drive and compare the archive contents against that data using the <code>-d</code> tar switch or keep the MD5 sums of the files in a separate document and also use an external program in order to check them against the calculated MD5 sums of the archived files. In this short post I introduce you to a method of creating tar archives and keeping the md5sums of the files at the same time and a utility, veritar, which can compare those md5 sums with the checksums of the contents of the archive in-place, without the need to extract.<br />
<span id="more-468"></span></p>
<h4>Creation of the TAR archive and the MD5 sums file</h4>
<p>In the following example it is assumed that the files to backup reside in the <code>myfiles/</code> subdirectory, the name of the tar archive will be <code>mybackup.tar</code> and the name of the file containing the md5sums will be <code>mybackup.md5</code>.</p>
<pre class="console">
$ tar -cvpf mybackup.tar myfiles/ \
    | xargs -I '{}' sh -c "test -f '{}' &#038;&#038; md5sum '{}'" \
    | tee mybackup.md5
</pre>
<p>Some notes:</p>
<ul>
<li>You can use any tar switch for the creation of the archive except <strong>-C</strong>. If you need to change to another directory, do it using <strong>cd</strong> or else no md5 sums will be recorded.</li>
<li>Make sure that you include the <strong>-v</strong> (<strong>&#8211;verbose</strong>) switch when invoking tar, as the paths need to be printed to stdout in order to be processed by <strong>xargs</strong>.</li>
<li>In the xargs statement, the <strong>-I &#8216;{}&#8217;</strong> part indicates that the <code>'{}'</code> string will be replaced by the path that is passed to xargs through the pipe.</li>
<li>The <strong>sh -c &#8220;test -f &#8216;{}&#8217; &#038;&#038; md5sum &#8216;{}&#8217;&#8221;</strong> does two things: tests if the path  (<code>'{}'</code>) is a file and calculates the md5 sum for it.</li>
<li>In the last part, <strong>tee</strong> is used in order to print the md5sum to the stdout and also to the <code>mybackup.md5</code> file.</li>
</ul>
<p>When this operation ends, you will end up with two files: <strong>mybackup.tar</strong> and <strong>mybackup.md5</strong>.</p>
<p><strong></strong><strong>Special thanks</strong> to:</p>
<p> <strong>*</strong> <em>Anvil</em> for the suggestion to use <code>bash -c "...test goes here..."</code> stuff.<br />
 <strong>*</strong> <em><a href="http://keramida.wordpress.com/">Giorgos Keramidas</a></em> for the improvement he suggested, so that the md5 sum calculation is not limited to regular files only:</p>
<pre class="codesnp">sh -c "test -d '{}' || md5sum '{}'"</pre>
<p>VeriTAR will verify the md5 sums of regular files only, so either test you use when creating the TAR archive, it is still fine.</p>
<h4>VeriTAR &#8211; Tar archive verification</h4>
<p><strong>VeriTAR</strong> [<code>Veri(fy)TAR</code>] is a command-line utility that verifies the md5 sums of files within a tar archive. Due to the tar (&#8216;<code>ustar</code>&#8216;) format limitations the md5 sums are retrieved from a separate file and are checked against the md5 sums of the files within the tar archive. The process takes place without actually exctracting the files.</p>
<p>It works with corrupted tar archives. The program carries on to the next file within the archive skipping the damaged parts. At the moment, this relies<br />
on Python&#8217;s tarfile module internal functions.</p>
<p>VeriTAR is written in Python.</p>
<p>Works with compressed TAR archives (gzip or bz2).</p>
<ul>
<li><a href="http://www.codetrax.org/projects/veritar/wiki">VeriTAR Development Website and Bug Tracking</a></li>
<li><a href="http://www.codetrax.org/projects/veritar/files">Downloads</a></li>
</ul>
<p>Provided that you have used the method above (or any other method) in order to create a file with the md5 sums together with the tar archive, you can easily verify the contents of the archive with veritar.</p>
<pre class="console">
$ veritar mybackup.tar mybackup.md5
</pre>
<p>Please not that veritar&#8217;s output and command line switched need some work, but for now it does the job.</p>
<p>Veritar is released under the <a href="http://www.codetrax.org/licenses/ApacheLicenseV2">Apache License version 2</a>.</p>
<p>It is completely unsupported, but you can still get community support at our software forums. This is also the place where you can inform me about any bugs.</p>
<h5>Known issues</h5>
<ol>
<li>Multi-volume tar archives are not supported at the moment</li>
<li>Tar archives in which the metadata of the first archived file has been corrupted cannot be processed due to a limitation in the tarfile Python module at the time of writing</li>
<li>Although the checksum of any algorithm, <strong>md5</strong>, <strong>sha1</strong>, <strong>crc</strong>(<strong>crc32</strong>), could be used, the current alpha version is not very flexible.</li>
<li>It may crash on damaged archives on older python versions.</li>
</ol>
<div class="cc-block"><em><a href="http://www.g-loaded.eu/2007/12/01/veritar-verify-checksums-of-files-within-a-tar-archive/">VeriTAR &#8211; Verify checksums of files within a TAR archive</a></em>, unless otherwise expressly stated, is licensed under a <a rel="license" href="http://creativecommons.org/licenses/by-nc-sa/3.0/">Creative Commons Attribution-Noncommercial-Share Alike 3.0 Unported License</a>. Terms and conditions beyond the scope of this license may be available at <a href="http://www.g-loaded.eu/about/disclaimer-and-license/">www.g-loaded.eu</a>.</div>
<h4>Related Articles</h4>
<ul><li><a href="http://www.g-loaded.eu/2006/10/07/verify-a-burned-cddvd-image-on-linux/" rel="bookmark">Verify a burned CD/DVD image on Linux</a></li>
<li><a href="http://www.g-loaded.eu/2007/12/01/choosing-a-format-for-data-backups-tar-vs-cpio/" rel="bookmark">Choosing a format for data backups &#8211; tar vs cpio</a></li>
<li><a href="http://www.g-loaded.eu/2008/01/28/how-to-extract-rpm-or-deb-packages/" rel="bookmark">How to extract RPM or DEB packages</a></li>
<li><a href="http://www.g-loaded.eu/2007/02/25/error-when-using-old-runbin-installers-under-linux/" rel="bookmark">Error when using old run/bin installers under Linux</a></li>
<li><a href="http://www.g-loaded.eu/2008/05/08/cheap-biometrics-use-keystroke-dynamics-to-identify-and-verify-users/" rel="bookmark">Cheap Biometrics &#8211; Use Keystroke Dynamics to Identify and Verify Users</a></li></ul>]]></content:encoded>
			<wfw:commentRss>http://www.g-loaded.eu/2007/12/01/veritar-verify-checksums-of-files-within-a-tar-archive/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
	<creativeCommons:license>http://creativecommons.org/licenses/by-nc-sa/3.0/</creativeCommons:license>
	</item>
		<item>
		<title>Upgraded to WordPress 2.3.1</title>
		<link>http://www.g-loaded.eu/2007/11/04/upgraded-to-wordpress-231/</link>
		<comments>http://www.g-loaded.eu/2007/11/04/upgraded-to-wordpress-231/#comments</comments>
		<pubDate>Sat, 03 Nov 2007 22:13:33 +0000</pubDate>
		<dc:creator>George Notaras</dc:creator>
				<category><![CDATA[Web Applications]]></category>
		<category><![CDATA[Maintenance]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[Scripts]]></category>
		<category><![CDATA[Shell]]></category>
		<category><![CDATA[Wordpress]]></category>
		<guid isPermaLink="false">http://www.g-loaded.eu/2007/11/04/upgraded-to-wordpress-231/</guid>
		<description><![CDATA[I finally made the decision to upgrade WordPress to the latest 2.3.1 version. I skipped the initial v2.3 release as I had read that there was a lengthy list of bugs about that release, which eventually have been fixed in 2.3.1. Everything seems to run smoothly. I intend to spend some time browsing around my [...]]]></description>
			<content:encoded><![CDATA[<p>I finally made the decision to upgrade WordPress to the latest 2.3.1 version. I skipped the initial v2.3 release as I had read that there was a lengthy list of bugs about that release, which eventually have been fixed in 2.3.1. Everything seems to run smoothly. I intend to spend some time browsing around my website to test it and by the way fix a few things here and there.</p>
<p>A while ago I had written a script that would automate the WordPress upgrade process. Such a program could have been a simple shell script, just a few lines of code. However, I decided to write a more flexible script in Python instead, which can keep backups, perform a thorough upgrade of the website&#8217;s platform, keep the files I need to keep etc. A script that takes good care of everything while upgrading is also a good idea because it minimizes downtime while performing upgrades. Today was the first time to test it. After the upgrade, everything seems to be where it should. The script is in pre-alpha state and despite the fact that I used it on my website, it is not ready for release yet. Below is the output of the upgrade on G-Loaded:<br />
<span id="more-455"></span></p>
<pre class="codesnp">
# python wpupgrade.py 2.3.1
info: ++ Performings Tests. Please wait...
info: Initial configuration checks - OK
info: Retrieval of WordPress database settings from wp-config.php - OK
info: Checking existence of mysqldump - OK
info: ++ Starting data backup. Please wait...
info: Database backup - OK
info: Filesystem backup - OK
info: Data backup Complete
info: ++ Downloading wordpress archive. Please wait...
info: Download and Verification Complete
info: ++ Removing old WordPress files and directories. Listing follows:
info: Removed DIR: wp-admin
info: Removed DIR: wp-includes - PRESERVED wp-includes/languages
warning: --> DIR wp-content/cache CANNOT BE REMOVED - NOT CRITICAL - REMOVE MANUALLY IF POSSIBLE
info: Removed FILE: wp-commentsrss2.php
info: Removed FILE: wp-rss.php
info: Removed FILE: wp-rdf.php
info: Removed FILE: wp-login.php
info: Removed FILE: wp-app.php
info: Removed FILE: wp-settings.php
info: Removed FILE: wp-comments-post.php
info: Removed FILE: wp-mail.php
info: Removed FILE: wp-rss2.php
info: Removed FILE: wp-pass.php
info: Removed FILE: wp-blog-header.php
info: Removed FILE: wp-register.php
info: Removed FILE: wp-feed.php
info: Removed FILE: wp-trackback.php
info: Removed FILE: wp-cron.php
info: Removed FILE: wp-links-opml.php
info: Removed FILE: wp-config-sample.php
info: Removed FILE: wp-atom.php
info: Removed FILE: index.php
info: Removed FILE: xmlrpc.php
info: Removed FILE: readme.html
info: Removed FILE: license.txt
info: WordPress files removal complete
info: ++ WordPress Upgrade
info: Writing new files. Please wait...
info: File Upgrade Complete
info: ++ Starting Cleanup
info: Nothing - TODO
info: Finish Upgrade by visiting: http://www.yoursite.org/wp-admin/upgrade.php
</pre>
<div class="cc-block"><em><a href="http://www.g-loaded.eu/2007/11/04/upgraded-to-wordpress-231/">Upgraded to WordPress 2.3.1</a></em>, unless otherwise expressly stated, is licensed under a <a rel="license" href="http://creativecommons.org/licenses/by-nc-sa/3.0/">Creative Commons Attribution-Noncommercial-Share Alike 3.0 Unported License</a>. Terms and conditions beyond the scope of this license may be available at <a href="http://www.g-loaded.eu/about/disclaimer-and-license/">www.g-loaded.eu</a>.</div>
<h4>Related Articles</h4>
<ul><li><a href="http://www.g-loaded.eu/2008/12/17/upgraded-to-wordpress-coltrane/" rel="bookmark">Upgraded to WordPress Coltrane</a></li>
<li><a href="http://www.g-loaded.eu/2006/01/01/upgraded-to-wordpress-2/" rel="bookmark">Upgraded to WordPress 2</a></li>
<li><a href="http://www.g-loaded.eu/2007/03/03/highly-exploitable-code-planted-into-wordpress-211/" rel="bookmark">Highly Exploitable Code Planted into WordPress 2.1.1</a></li>
<li><a href="http://www.g-loaded.eu/2007/02/09/server-upgraded-to-fedora-6/" rel="bookmark">Server upgraded to Fedora 6</a></li>
<li><a href="http://www.g-loaded.eu/2008/03/31/wordpress-25-plugin-compatibility/" rel="bookmark">WordPress 2.5 &#8211; Plugin Compatibility</a></li></ul>]]></content:encoded>
			<wfw:commentRss>http://www.g-loaded.eu/2007/11/04/upgraded-to-wordpress-231/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	<creativeCommons:license>http://creativecommons.org/licenses/by-nc-sa/3.0/</creativeCommons:license>
	</item>
		<item>
		<title>Fixed: tab-session-management.py now works with Python 2.5</title>
		<link>http://www.g-loaded.eu/2007/05/18/fixed-tab-session-managementpy-now-works-with-python-25/</link>
		<comments>http://www.g-loaded.eu/2007/05/18/fixed-tab-session-managementpy-now-works-with-python-25/#comments</comments>
		<pubDate>Fri, 18 May 2007 09:34:13 +0000</pubDate>
		<dc:creator>George Notaras</dc:creator>
				<category><![CDATA[Linux]]></category>
		<category><![CDATA[Epiphany]]></category>
		<category><![CDATA[Plugins]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[Resolved]]></category>
		<category><![CDATA[Updates]]></category>
		<guid isPermaLink="false">http://www.g-loaded.eu/2007/05/18/fixed-tab-session-managementpy-now-works-with-python-25/</guid>
		<description><![CDATA[This is a notice that I have updated the tab-session-management extension for Epiphany, so to make it work in environments that use Python version 2.5. This mainly involves the newest Fedora and Ubuntu distributions &#8211; at the time of writing. The plugin makes use of the cElementTree module, which has been moved into Python&#8217;s Standard [...]]]></description>
			<content:encoded><![CDATA[<p>This is a notice that I have updated the <a href="http://www.g-loaded.eu/2006/05/16/tab-session-management-extension-for-epiphany/">tab-session-management</a> extension for Epiphany, so to make it work in environments that use <a href="http://python.org/">Python</a> version 2.5. This mainly involves the newest <a href="http://fedoraproject.org/">Fedora</a> and <a href="http://www.ubuntu.com/">Ubuntu</a> distributions &#8211; at the time of writing. The plugin makes use of the <a href="http://effbot.org/zone/celementtree.htm">cElementTree</a> module, which has been <a href="http://docs.python.org/lib/module-xml.etree.ElementTree.html">moved</a> into Python&#8217;s Standard Library in Python v2.5, inside the <code>xml</code> package (<code>xml.etree.cElementTree</code>). This issue has been <strong>addressed</strong> in the <strong>0.2</strong> version of the extension. Furthermore, the extension&#8217;s homepage has been updated with much more information. Last, but not least, a <strong>Nautilus action</strong>, which makes it possible to load saved tab sessions right from within Nautilus, has been added for download.</p>
<div class="cc-block"><em><a href="http://www.g-loaded.eu/2007/05/18/fixed-tab-session-managementpy-now-works-with-python-25/">Fixed: tab-session-management.py now works with Python 2.5</a></em>, unless otherwise expressly stated, is licensed under a <a rel="license" href="http://creativecommons.org/licenses/by-nc-sa/3.0/">Creative Commons Attribution-Noncommercial-Share Alike 3.0 Unported License</a>. Terms and conditions beyond the scope of this license may be available at <a href="http://www.g-loaded.eu/about/disclaimer-and-license/">www.g-loaded.eu</a>.</div>
<h4>Related Articles</h4>
<ul><li><a href="http://www.g-loaded.eu/2006/05/16/tab-session-management-extension-for-epiphany/" rel="bookmark">Tab Session Management extension for Epiphany</a></li>
<li><a href="http://www.g-loaded.eu/2006/05/17/epiphany-python-console-documentation/" rel="bookmark">Epiphany Python Console &#8211; Documentation</a></li>
<li><a href="http://www.g-loaded.eu/2007/02/28/tab-links-extension-for-the-epiphany-browser/" rel="bookmark">Tab Links extension for the Epiphany browser</a></li>
<li><a href="http://www.g-loaded.eu/2007/09/14/featured-epiphany-plugins/" rel="bookmark">Featured Epiphany Plugins</a></li>
<li><a href="http://www.g-loaded.eu/2006/05/04/more-on-celementtree/" rel="bookmark">More On cElementTree</a></li></ul>]]></content:encoded>
			<wfw:commentRss>http://www.g-loaded.eu/2007/05/18/fixed-tab-session-managementpy-now-works-with-python-25/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	<creativeCommons:license>http://creativecommons.org/licenses/by-nc-sa/3.0/</creativeCommons:license>
	</item>
	</channel>
</rss>

