<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-33763744</id><updated>2011-11-27T20:13:35.894-05:00</updated><category term='apache'/><category term='debug'/><category term='plone'/><category term='workaround'/><category term='python'/><category term='wsgi'/><category term='spam'/><category term='zope'/><category term='zodb'/><category term='scm'/><category term='freebsd'/><category term='zope3'/><category term='osx'/><category term='ipython'/><category term='LDAP'/><category term='svn'/><title type='text'>Independent Suspension</title><subtitle type='html'>Um, a blog.</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://reedobrien.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/33763744/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://reedobrien.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>reedobrien</name><uri>http://www.blogger.com/profile/15835081896608317143</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>19</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-33763744.post-4356098949830586875</id><published>2008-05-26T03:18:00.000-04:00</published><updated>2008-05-26T03:47:55.968-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='freebsd'/><category scheme='http://www.blogger.com/atom/ns#' term='workaround'/><title type='text'>Using a TCP proxy to bypass firewall</title><content type='html'>In the middle of a month long holiday in Africa, I finally am at a place where I can connect my notebook to the internet. I have been able to get to my mail via webmail, but I don't have all the filters I like set up on the webmail system, so it is still way to noisy to get past all the mailing lists...&lt;br /&gt;&lt;br /&gt;IMAP is a blessing. Except when the provider firewall blocks port 993. In this particular case it doesn't block 10993 though, so I decided to set up a proxy which would get me my mail.  It was really quite simple.&lt;br /&gt;&lt;br /&gt;So this is an example of how to use balance on freebsd 7 to set up a proxy for a TCP service. In my case i am proxying imaps via an unprivileged port on my utility server to the imaps port on the actual mail server.&lt;br /&gt;&lt;br /&gt;I connected to my freebsd box over ublocked ssh and... &lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;reed@host $ cd /usr/ports/net/balance&lt;br /&gt;reed@host $ sudo make install&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;I did a quick connection test like so:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;reed@host $ sudo balance -fp 10993 mail.serverbox.com:993&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;and a quick telnet confirmed connection to the destination so I then added some config to rc.conf:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;### balance                                                                                                                             &lt;br /&gt;balance_enable="YES"&lt;br /&gt;balance_hosts="host1"&lt;br /&gt;balance_host1_address="my.proxy.box.com"&lt;br /&gt;balance_host1_ports="10993"&lt;br /&gt;balance_host1_targets="mail.server.box.com:imaps"&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;And I am now receiving and filtering email with Mail...&lt;br /&gt;&lt;br /&gt;Cake&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/33763744-4356098949830586875?l=reedobrien.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://reedobrien.blogspot.com/feeds/4356098949830586875/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=33763744&amp;postID=4356098949830586875' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/33763744/posts/default/4356098949830586875'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/33763744/posts/default/4356098949830586875'/><link rel='alternate' type='text/html' href='http://reedobrien.blogspot.com/2008/05/using-tcp-proxy-to-bypass-firewall.html' title='Using a TCP proxy to bypass firewall'/><author><name>reedobrien</name><uri>http://www.blogger.com/profile/15835081896608317143</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-33763744.post-5264395543357680795</id><published>2008-04-14T11:53:00.000-04:00</published><updated>2008-04-14T11:54:14.289-04:00</updated><title type='text'>create an installer dmg of a program</title><content type='html'>Open the PackageMaker program.&lt;br /&gt;Click "Assist me..."&lt;br /&gt;Add the files you want to install and give them a destination on the destination drive.&lt;br /&gt;Select files appropriate for a Welcome page, README, license, and conclusion.&lt;br /&gt;Add a bg image if so desired.&lt;br /&gt;&lt;br /&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;br /&gt;Save and move to the directory in a terminal then&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;$hdiutil create Subversion-1.4.3 -srcFolder ~/projects/Subversion-1.4.3.mpkg&lt;br /&gt;&lt;/p&gt;&lt;br /&gt;&lt;p&gt;viola!&lt;br /&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/33763744-5264395543357680795?l=reedobrien.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://reedobrien.blogspot.com/feeds/5264395543357680795/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=33763744&amp;postID=5264395543357680795' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/33763744/posts/default/5264395543357680795'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/33763744/posts/default/5264395543357680795'/><link rel='alternate' type='text/html' href='http://reedobrien.blogspot.com/2008/04/create-installer-dmg-of-program.html' title='create an installer dmg of a program'/><author><name>reedobrien</name><uri>http://www.blogger.com/profile/15835081896608317143</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-33763744.post-2728505689000739325</id><published>2008-04-14T11:21:00.000-04:00</published><updated>2008-04-14T11:22:16.536-04:00</updated><title type='text'>Aquamacs and Python</title><content type='html'>Aquamacs with Python completion and ipython&lt;br /&gt;&lt;br /&gt;&lt;ol type="1"&gt;&lt;li&gt;Install &lt;a href="http://pymacs.progiciels-bpi.ca/"&gt;Pymacs&lt;/a&gt;  (python setup.py install)  &lt;/li&gt;&lt;li&gt;Make sure you have pymac-services and rebox in your PATH. They install where the python binaries are.&lt;/li&gt;&lt;li&gt;Install python-mode.el in your site-lisp (/Library/Application\ Support/Emacs/site-lisp (create if necessary))&lt;/li&gt;&lt;br /&gt;&lt;ol&gt;&lt;li&gt;from the &lt;a href="http://python-mode.sourceforge.net/"&gt;python mode&lt;/a&gt; folder copy pycomplete.py to your python site-packages (or otherwise add it to your python path.) and the .el files to your site-lisp directory&lt;br /&gt;&lt;/li&gt;&lt;/ol&gt;&lt;br /&gt;&lt;li&gt;Install &lt;a href="http://ipython.scipy.org/moin/"&gt;ipython&lt;/a&gt;&lt;/li&gt;&lt;li&gt;edit your .emacs &lt;/li&gt;&lt;/ol&gt;&lt;br /&gt;&lt;p align="center" class="discreet"&gt;(your path may differ, as well as your mileage)&lt;/p&gt;&lt;br /&gt;&lt;pre&gt;(setq auto-mode-alist (cons '("\\.py$" . python-mode) auto-mode-alist))&lt;br /&gt;(setq interpreter-mode-alist (cons '("python" . python-mode) interpreter-mode-alist))&lt;br /&gt;(autoload 'python-mode "python-mode" "Python editing mode." t)&lt;br /&gt;(autoload 'pymacs-load "pymacs" nil t)&lt;br /&gt;(autoload 'pymacs-eval "pymacs" nil t)&lt;br /&gt;(autoload 'pymacs-apply "pymacs")&lt;br /&gt;(autoload 'pymacs-call "pymacs")&lt;br /&gt;(require 'pycomplete)&lt;br /&gt;(setq ipython-command "/Library/Frameworks/Python.framework/Versions/Current/bin/ipython")&lt;br /&gt;(require 'ipython)&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/33763744-2728505689000739325?l=reedobrien.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://reedobrien.blogspot.com/feeds/2728505689000739325/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=33763744&amp;postID=2728505689000739325' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/33763744/posts/default/2728505689000739325'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/33763744/posts/default/2728505689000739325'/><link rel='alternate' type='text/html' href='http://reedobrien.blogspot.com/2008/04/aquamacs-and-python.html' title='Aquamacs and Python'/><author><name>reedobrien</name><uri>http://www.blogger.com/profile/15835081896608317143</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-33763744.post-1667186468973859174</id><published>2008-04-08T21:18:00.000-04:00</published><updated>2008-04-08T21:49:46.600-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='apache'/><category scheme='http://www.blogger.com/atom/ns#' term='plone'/><category scheme='http://www.blogger.com/atom/ns#' term='zope'/><title type='text'>Mapping specific requests to a single ZEO client instance</title><content type='html'>As a follow up to &lt;a href="http://reedobrien.blogspot.com/2008/01/apache-round-robin-for-zeoclients.html"&gt;Apache Round Robin for ZeoClients&lt;/a&gt;: &lt;br /&gt;&lt;br /&gt;we needed to send session specific things to a single instance.&lt;br /&gt;&lt;br /&gt;An example of why this is necessary is for &lt;a href="http://pypi.python.org/pypi/collective.captcha/1.3"&gt;collective.captcha&lt;/a&gt;. If the connections are being round robin-ed you get audio and image files from different instances. That is BAD.  It doesn't work.&lt;br /&gt;&lt;br /&gt;First make sure varnish doesn't cache the captcha images and audio or your captcha protected form page.&lt;br /&gt;In varnish.vcl add:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;# Do NOT cache captcha image, audio, request&lt;br /&gt;  if (   req.url ~ "/@@captcha"&lt;br /&gt;      || req.url ~ "/contact-info"&lt;br /&gt;     ) {&lt;br /&gt;        pipe;&lt;br /&gt;       }&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Next we need to map a server to do our captcha stuff. &lt;br /&gt;In zopeservers.map add the line:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;CAPTCHA localhost:6970&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;I will leave it to you to think of how to creatively balance requests to the other instances. Perhaps remove teh one that does some captcha and other special work from ALL, or maybe add the other instances more than once... OK I didn't leave much, but there are probably smarter ways to do it.&lt;br /&gt;&lt;br /&gt;Finally we need to add a rule for mapping captcha requests to the correct instance.&lt;br /&gt;To the appropriate apache.conf (http.conf) add: &lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;RewriteRule ^/(@@captcha/(audio|image)|contact-info)   \&lt;br /&gt;   http://${zopeservers:CAPTCHA}/VirtualHostBase/http/%{SERVER_NAME}:80/msrd/VirtualHostRoot/$1 [L,P]&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;Don't forget to restart apache and varnish!!&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Thanks to &lt;a href="http://chris.shenton.org/resume/"&gt;Chris Shenton&lt;/a&gt; for suggesting the solution.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/33763744-1667186468973859174?l=reedobrien.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://reedobrien.blogspot.com/feeds/1667186468973859174/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=33763744&amp;postID=1667186468973859174' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/33763744/posts/default/1667186468973859174'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/33763744/posts/default/1667186468973859174'/><link rel='alternate' type='text/html' href='http://reedobrien.blogspot.com/2008/04/mapping-specific-requests-to-single-zeo.html' title='Mapping specific requests to a single ZEO client instance'/><author><name>reedobrien</name><uri>http://www.blogger.com/profile/15835081896608317143</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-33763744.post-8027538839133876262</id><published>2008-02-26T18:04:00.000-05:00</published><updated>2008-02-26T18:10:17.796-05:00</updated><title type='text'>Error building psycopg custom egg</title><content type='html'>I was running a buildout and got this error:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;/psycopg/config.h:119: error: static declaration of 'round' follows non-static declaration&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;I know little to nothing about C so I asked Chris Shenton.  He said, "Sounds like it is already defined. Try commenting it out."  It worked.&lt;br /&gt;&lt;br /&gt;I assume this is new in FreeBSD 7 which I am running. So I think this should work:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;--- psycopg/config.h    2008-02-26 21:47:43 +0000&lt;br /&gt;+++ psycopg/config.h    2008-02-26 21:56:06 +0000&lt;br /&gt;@@ -113,7 +113,7 @@&lt;br /&gt; #define inline&lt;br /&gt; #endif&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;-#if defined(__FreeBSD__) || (defined(_WIN32) &amp;&amp; !defined(__GNUC__)) || defined(__sun__)&lt;br /&gt;+#if defined(__FREEBSD__ &lt; 7) || (defined(_WIN32) &amp;&amp; !defined(__GNUC__)) || defined(__sun__)&lt;br /&gt; /* what's this, we have no round function either? */&lt;br /&gt; static double round(double num)&lt;br /&gt; {&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;I went to file a bug at initd.org, but their system was down. So I put it here.  Thanks for the clue Chris.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/33763744-8027538839133876262?l=reedobrien.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://reedobrien.blogspot.com/feeds/8027538839133876262/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=33763744&amp;postID=8027538839133876262' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/33763744/posts/default/8027538839133876262'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/33763744/posts/default/8027538839133876262'/><link rel='alternate' type='text/html' href='http://reedobrien.blogspot.com/2008/02/error-building-psycopg-custom-egg.html' title='Error building psycopg custom egg'/><author><name>reedobrien</name><uri>http://www.blogger.com/profile/15835081896608317143</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-33763744.post-2340260300607498576</id><published>2008-01-15T18:21:00.000-05:00</published><updated>2008-01-15T18:48:03.943-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='apache'/><category scheme='http://www.blogger.com/atom/ns#' term='plone'/><category scheme='http://www.blogger.com/atom/ns#' term='zope'/><title type='text'>Apache Round Robin for ZeoClients</title><content type='html'>There is a common approach to running Plone/Zope behind some service that distributes requests across numerous ZeoClients. Here's how I have been doing it using Apache (2.2.x).&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;&lt;br /&gt;                                  ________Zeoclient(6968)&lt;br /&gt;                                 | _______ZeoClient(6969)&lt;br /&gt;client--&gt;varnish(80)--&gt;apache(81)|&lt;_______ZeoClient(6970)&lt;br /&gt;                                 |________ZeoClient(6971)&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Everybody knows how to setup varnish, right? So I am only going to show the Apache bits here.&lt;br /&gt;&lt;br /&gt;First you need a rewrite map.&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;#zopeservers.map&lt;br /&gt;ALL     localhost:6968|localhost:6969|localhost:6970|localhost:6917&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Of course there can be more or less hosts in the map and they don't have to be all localhost either.&lt;br /&gt;&lt;br /&gt;Next you need to enter the right stuff in the apache configuration. As here in a VirtualHost.&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;&amp;lt;VirtualHost *:81&amp;gt;&lt;br /&gt;...&lt;br /&gt;RewriteMap  zopeservers rnd:/usr/local/apache2/conf/zopeservers.map&lt;br /&gt;RewriteRule ^/(.*) \&lt;br /&gt;    http://${zopeservers:ALL}/VirtualHostBase/http/%{SERVER_NAME}:80/ploneroot/VirtualHostRoot/$1 [L,P]&lt;br /&gt;...&lt;br /&gt;&amp;lt;/VirtualHost&amp;gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;How does Emiril say... BAM!&lt;br /&gt;&lt;br /&gt;Not so hard at all. A couple of notes:&lt;br /&gt;&lt;br /&gt;1. I don't think apache knows how to detect if a client is down or broken.  So it will serve up all the errors it gets.&lt;br /&gt;&lt;br /&gt;2. Varnish doesn't cache https, so it needs to be handled wihtout varnish...&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/33763744-2340260300607498576?l=reedobrien.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://reedobrien.blogspot.com/feeds/2340260300607498576/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=33763744&amp;postID=2340260300607498576' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/33763744/posts/default/2340260300607498576'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/33763744/posts/default/2340260300607498576'/><link rel='alternate' type='text/html' href='http://reedobrien.blogspot.com/2008/01/apache-round-robin-for-zeoclients.html' title='Apache Round Robin for ZeoClients'/><author><name>reedobrien</name><uri>http://www.blogger.com/profile/15835081896608317143</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-33763744.post-3997909550366546495</id><published>2008-01-12T00:19:00.000-05:00</published><updated>2008-07-07T21:27:08.080-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='LDAP'/><category scheme='http://www.blogger.com/atom/ns#' term='python'/><title type='text'>Seeded (Salted) SHA Passwords</title><content type='html'>This week I needed to work with passwords from an OpenLDAP database.  I needed to create users and encode their passwords as SSHA.  After much googling and reading of authentication code examples, this is what I came up with.&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;import hashlib&lt;br /&gt;import os&lt;br /&gt;from base64 import urlsafe_b64encode as encode&lt;br /&gt;from base64 import urlsafe_b64decode as decode&lt;br /&gt;&lt;br /&gt;def makeSecret(password):&lt;br /&gt; salt = os.urandom(4)&lt;br /&gt; h = hashlib.sha1(password)&lt;br /&gt; h.update(salt)&lt;br /&gt; return "{SSHA}" + encode(h.digest() + salt)&lt;br /&gt;&lt;br /&gt;def checkPassword(challenge_password, password):&lt;br /&gt; challenge_bytes = decode(challenge_password[6:])&lt;br /&gt; digest = challenge_bytes[:20]&lt;br /&gt; salt = challenge_bytes[20:]&lt;br /&gt; hr = hashlib.sha1(password)&lt;br /&gt; hr.update(salt)&lt;br /&gt; return digest == hr.digest()&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Wow, python rules. So first I want to make sure I can validate a password against one generated by slappasswd&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;reedobrien$ slappasswd -s topsecret&lt;br /&gt;{SSHA}Ccpjsip2UZL2CR2VsWTH7aF0vWKHQ7jn&lt;br /&gt;&lt;/pre&gt;And then see if I can validate it&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;&gt;&gt;&gt; checkPassword('{SSHA}Ccpjsip2UZL2CR2VsWTH7aF0vWKHQ7jn',&lt;br /&gt;...               'topsecret')&lt;br /&gt;   True&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Next I need to make sure I can generate one that OpenLDAP can use. So I used a script I wrote to create a user in ldap. This time I use the same password and get a different hash which is good.&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;&gt;&gt;&gt; pw = "{SSHA}hq5ROYE8RoLA1Zcz6azgNQP5PkdETocx"&lt;br /&gt;&lt;/pre&gt; &lt;br /&gt;which OpenLDAP represents in LDIFs as base64 encoded&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;...&lt;br /&gt;# tester, people, reedobrien.com&lt;br /&gt;dn: uid=tester,ou=people,dc=reedobrien,dc=com&lt;br /&gt;objectClass: top&lt;br /&gt;objectClass: inetOrgPerson&lt;br /&gt;uid: tester&lt;br /&gt;cn: test test&lt;br /&gt;sn: test&lt;br /&gt;mail: test@example.com&lt;br /&gt;userPassword:: e1NTSEF9MHhaMEdZc2Fob1JNeXZWR2FVdGszS0VwSFZTQnVLTlc=&lt;br /&gt;...&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;So I try authenticating:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;&gt;&gt;&gt; userPasword = "e1NTSEF9MHhaMEdZc2Fob1JNeXZWR2FVdGszS0VwSFZTQnVLTlc="&lt;br /&gt;&lt;br /&gt;&gt;&gt;&gt; decode(userPassword) == pw&lt;br /&gt;    True&lt;br /&gt;&lt;br /&gt;&gt;&gt;&gt; checkPassword(decode(userPassword), 'topsecret')&lt;br /&gt;    True&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Now I want to make sure it works through the ldap server itself&lt;br /&gt;In python:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;&lt;br /&gt;&gt;&gt;&gt; import ldap&lt;br /&gt;&lt;br /&gt;&gt;&gt;&gt; con = ldap.initialize("ldap://127.0.0.1")&lt;br /&gt;&gt;&gt;&gt; con.simple_bind_s('uid=tester,ou=people,dc=reedbrien,dc=com',&lt;br /&gt;                      'topsecret')&lt;br /&gt;    (97, []) ## indicates success&lt;br /&gt;&lt;/pre&gt; &lt;br /&gt;And not using my stuff.&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;reedobrien$ ldapsearch -x -D "uid=tester,ou=people,dc=reedobrien,dc=com" -w topsecret&lt;br /&gt;# extended LDIF&lt;br /&gt;#&lt;br /&gt;# LDAPv3&lt;br /&gt;# base &lt;&gt; with scope sub&lt;br /&gt;# filter: (objectclass=*)&lt;br /&gt;# requesting: ALL&lt;br /&gt;#&lt;br /&gt;&lt;br /&gt;# search result&lt;br /&gt;search: 2&lt;br /&gt;result: 32 No such object&lt;br /&gt;&lt;br /&gt;# numResponses: 1&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;How do they say, `w00t!`&lt;br /&gt;&lt;br /&gt;So it was cool doing it and it made me feel smart for a minute. I am sure that there is a module or ten out there that already does this, but I couldn't find it. At least it was educational.&lt;br /&gt;&lt;br /&gt;Unfortunately, after getting it to work; I don't I understand any better what it really does or how SSHA is better than plain old SHA.&lt;br /&gt;&lt;br /&gt;Oh, well.  Hopefully it helps some weary traveller out there one day.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/33763744-3997909550366546495?l=reedobrien.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://reedobrien.blogspot.com/feeds/3997909550366546495/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=33763744&amp;postID=3997909550366546495' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/33763744/posts/default/3997909550366546495'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/33763744/posts/default/3997909550366546495'/><link rel='alternate' type='text/html' href='http://reedobrien.blogspot.com/2008/01/seeded-salted-sha-passwords.html' title='Seeded (Salted) SHA Passwords'/><author><name>reedobrien</name><uri>http://www.blogger.com/profile/15835081896608317143</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-33763744.post-1263659019251585941</id><published>2008-01-11T16:07:00.000-05:00</published><updated>2008-01-11T19:02:38.224-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='wsgi'/><category scheme='http://www.blogger.com/atom/ns#' term='python'/><category scheme='http://www.blogger.com/atom/ns#' term='zodb'/><category scheme='http://www.blogger.com/atom/ns#' term='zope'/><title type='text'>Serving up a ZODB on demand from a repozo backup</title><content type='html'>Since I said I would on the &lt;a href="http://www.nabble.com/Is-replacing-a-Data.fs-file-a-more-reliable-way-to-migrate-to-a-production-environment-than-is-exporting-to-a-.zexp-file--td14624422s6741.html#a14638084"&gt;mailing list/forum&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Here it is:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;import os&lt;br /&gt;import shutil&lt;br /&gt;import tarfile&lt;br /&gt;import tempfile&lt;br /&gt;&lt;br /&gt;def application(environ, start_response):&lt;br /&gt;  status = '200 OK'&lt;br /&gt;&lt;br /&gt;  tempdir  = tempfile.mkdtemp()&lt;br /&gt;  datafile = '%s/Data.fs' % tempdir&lt;br /&gt;  tarball = '%s.tar.bz2' % os.path.join(tempdir,&lt;br /&gt;                                        os.path.basename(datafile))&lt;br /&gt;&lt;br /&gt;  ## If I were smarter or had more time&lt;br /&gt;  ## I would import from repozo or at&lt;br /&gt;  ## least use subprocess&lt;br /&gt;  os.system("/usr/local/zope/2.9.7/bin/repozo.py -v -z -R -r \&lt;br /&gt;         /usr/local/zope/sites/2.9.7/msrd/zeo/var/backup/ -o %s" % datafile)&lt;br /&gt;&lt;br /&gt;  out = tarfile.TarFile.open(tarball, 'w:bz2')&lt;br /&gt;  os.chdir(tempdir)&lt;br /&gt;  out.add('Data.fs')&lt;br /&gt;  out.close()&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;  response_headers = [('Content-type', 'application/octet-stream'),&lt;br /&gt;                      ('Content-Length', str(len(open(tarball).read()))),&lt;br /&gt;                      ('Content-Disposition',&lt;br /&gt;                       'inline; filename="Data.fs.tar.bz2"')]&lt;br /&gt;&lt;br /&gt;  start_response(status, response_headers)&lt;br /&gt;  try:&lt;br /&gt;      return [open(tarball, 'rb').read()]&lt;br /&gt;  finally:&lt;br /&gt;      shutil.rmtree(tempdir)&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;I did it really quick. But it solved my problem very well.  It gets a copy of the Data.fs from the last repozo backup. So all developers don't need shell access to the server...&lt;br /&gt;&lt;br /&gt;A couple things I could see doing that would make this cooler are:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Not using os.system&lt;/li&gt;&lt;li&gt;implement a method to do HEAD requests with the time of the last repozo delta so I don't compress and transfer this beast if there are no changes...&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;If you have mod_wsgi installed and working you just need to add something like:&lt;br /&gt;&lt;br /&gt;WSGIScriptAlias /Data.fs.tar.bz2 /usr/local/apps/getDataArchived.py&lt;br /&gt;&lt;br /&gt;to the appropriate configuration file.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/33763744-1263659019251585941?l=reedobrien.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://reedobrien.blogspot.com/feeds/1263659019251585941/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=33763744&amp;postID=1263659019251585941' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/33763744/posts/default/1263659019251585941'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/33763744/posts/default/1263659019251585941'/><link rel='alternate' type='text/html' href='http://reedobrien.blogspot.com/2008/01/serving-up-zodb-on-demand-from-repozo.html' title='Serving up a ZODB on demand from a repozo backup'/><author><name>reedobrien</name><uri>http://www.blogger.com/profile/15835081896608317143</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-33763744.post-5539345407410666512</id><published>2007-12-16T22:19:00.000-05:00</published><updated>2008-01-11T19:03:33.597-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='scm'/><category scheme='http://www.blogger.com/atom/ns#' term='svn'/><title type='text'>Migrate a Subversion Sub Repository</title><content type='html'>&lt;h3&gt;Migrate SVN&lt;/h3&gt;&lt;br /&gt;Description:&lt;br /&gt;&lt;br /&gt;Instructions to migrate a sub repository to it's own repository.&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;&lt;br /&gt;&lt;/span&gt;Get a copy of the repo:&lt;br /&gt;&lt;div class="section" id="migrate-svn"&gt;&lt;pre class="literal-block"&gt;    cp -r me@myserver:/usr/local/data/svn/myrepo .&lt;br /&gt;&lt;/pre&gt;Dump it:&lt;pre class="literal-block"&gt;&lt;br /&gt;svnadmin dump --quiet myrepo &amp;gt; myrepo.DUMP&lt;br /&gt;&lt;/pre&gt;Filter the hunk you want:&lt;br /&gt;&lt;pre class="literal-block"&gt;&lt;br /&gt;cat myrepo.DUMP | svndumpfilter include MySubProject &amp;gt; MySubProject.DUMP|more&lt;br /&gt;&lt;/pre&gt;&lt;p&gt;copy it to the new server (omit this if doing it on the new server):&lt;/p&gt;&lt;pre class="literal-block"&gt;&lt;br /&gt;scp MySubProject.DUMP robrien@myotherserver:~/&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;p&gt;Logon:&lt;/p&gt;&lt;pre class="literal-block"&gt;&lt;br /&gt; ssh robrien@myotherserver&lt;br /&gt;&lt;/pre&gt;&lt;p&gt;Create a new repo:&lt;/p&gt;&lt;pre class="literal-block"&gt;&lt;br /&gt; sudo ./bin/svnadmin create /usr/local/repos/MySubProject&lt;br /&gt; sudo chown -R www:www /usr/local/repos/&lt;br /&gt;&lt;/pre&gt;&lt;p&gt;Load the repo:&lt;/p&gt;&lt;pre class="literal-block"&gt;    sudo svnadmin load --quiet /usr/local/repos/MySubProject &amp;lt; /usr/home/robrien/MySubProject.DUMP&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;Done.&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/33763744-5539345407410666512?l=reedobrien.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://reedobrien.blogspot.com/feeds/5539345407410666512/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=33763744&amp;postID=5539345407410666512' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/33763744/posts/default/5539345407410666512'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/33763744/posts/default/5539345407410666512'/><link rel='alternate' type='text/html' href='http://reedobrien.blogspot.com/2007/12/migrate-subversion-sub-repository.html' title='Migrate a Subversion Sub Repository'/><author><name>reedobrien</name><uri>http://www.blogger.com/profile/15835081896608317143</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-33763744.post-4807779912827395285</id><published>2007-10-29T21:26:00.000-04:00</published><updated>2008-01-11T19:04:48.104-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='python'/><category scheme='http://www.blogger.com/atom/ns#' term='osx'/><title type='text'>Build PIL on Mac OSX</title><content type='html'>&lt;span style="color: rgb(0, 153, 0);"&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;This entry attempts to give instructions for how to build the Python Imaging Library (PIL) on Mac OSX.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;#download and untar the jpeg library&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 153, 0);"&gt;#see here for location http://www.ijg.org/&lt;/span&gt;&lt;br /&gt;&lt;pre&gt;curl http://path/to/jpegsrc.v6b.tar.gz | tar zxf -&lt;/pre&gt;&lt;span style="color: rgb(0, 153, 0);"&gt;#change directory to&lt;/span&gt;&lt;br /&gt;&lt;pre&gt;cd jpeg-6b&lt;/pre&gt;&lt;span style="color: rgb(0, 153, 0);"&gt;#run configure&lt;/span&gt;&lt;br /&gt;&lt;pre&gt;./configure CFLAGS='-fPIC'&lt;/pre&gt;&lt;span style="color: rgb(0, 153, 0);"&gt;#run make&lt;/span&gt;&lt;br /&gt;&lt;pre&gt;make&lt;/pre&gt;&lt;span style="color: rgb(0, 153, 0);"&gt;#Run make install&lt;/span&gt;&lt;br /&gt;&lt;pre&gt;sudo make install&lt;/pre&gt;&lt;span style="color: rgb(0, 153, 0);"&gt;#run ranlib&lt;/span&gt;&lt;br /&gt;&lt;pre&gt;ranlib libjpeg.a&lt;/pre&gt;&lt;span style="color: rgb(0, 153, 0);"&gt;#copy the lib file to lib&lt;/span&gt;&lt;br /&gt;&lt;pre&gt;cp libjpeg.a /usr/local/lib&lt;/pre&gt;&lt;span style="color: rgb(0, 153, 0);"&gt;#copy headers to include&lt;/span&gt;&lt;br /&gt;&lt;pre&gt;cp *.h /usr/local/include&lt;/pre&gt;&lt;span style="color: rgb(0, 153, 0);"&gt;#make this your real python&lt;/span&gt;&lt;br /&gt;&lt;pre&gt;PYTHON_COMMAND="/path/to/your/python"&lt;/pre&gt;&lt;span style="color: rgb(0, 153, 0);"&gt;#get and untar the PIL source&lt;/span&gt;&lt;br /&gt;&lt;pre&gt;curl http://path/to/Imaging-1.1.6.tar.gz | tar zxf -&lt;/pre&gt;&lt;span style="color: rgb(0, 153, 0);"&gt;# cd&lt;/span&gt;&lt;br /&gt;&lt;pre&gt;cd Imaging-1.1.6&lt;/pre&gt;&lt;span style="color: rgb(0, 153, 0);"&gt;# copy setup out of it's way&lt;/span&gt;&lt;br /&gt;&lt;pre&gt;mv setup.py setup.py.tmp&lt;/pre&gt;&lt;span style="color: rgb(0, 153, 0);"&gt;# set up a replacement command&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 153, 0);"&gt;# you can do edit setup.py by hand if you wish&lt;/span&gt;&lt;br /&gt;&lt;pre&gt;SED_CMD="s|JPEG_ROOT = None|JPEG_ROOT = libinclude(\"/usr/local/lib\")|; s|ZLIB_ROOT = None|ZLIB_ROOT = libinclude(\"/usr/local/lib\")|;"&lt;/pre&gt;&lt;span style="color: rgb(0, 153, 0);"&gt;#replace the stock jpg locations with the new ones you made&lt;/span&gt;&lt;br /&gt;&lt;pre&gt;cat setup.py.tmp | sed -e "$SED_CMD" &gt; setup.py&lt;/pre&gt;&lt;span style="color: rgb(0, 153, 0);"&gt;#build it&lt;/span&gt;&lt;br /&gt;&lt;pre&gt;$PYTHON_COMMAND setup.py build_ext -i&lt;/pre&gt;&lt;span style="color: rgb(0, 153, 0);"&gt;#test it&lt;/span&gt;&lt;br /&gt;&lt;pre&gt;$PYTHON_COMMAND selftest.py&lt;/pre&gt;&lt;span style="color: rgb(0, 153, 0);"&gt;#install it&lt;/span&gt;&lt;br /&gt;&lt;pre&gt;sudo $PYTHON_COMMAND setup.py install&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/33763744-4807779912827395285?l=reedobrien.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://reedobrien.blogspot.com/feeds/4807779912827395285/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=33763744&amp;postID=4807779912827395285' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/33763744/posts/default/4807779912827395285'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/33763744/posts/default/4807779912827395285'/><link rel='alternate' type='text/html' href='http://reedobrien.blogspot.com/2007/10/pil-on-macosx.html' title='Build PIL on Mac OSX'/><author><name>reedobrien</name><uri>http://www.blogger.com/profile/15835081896608317143</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-33763744.post-1835724234761725475</id><published>2007-10-24T14:34:00.000-04:00</published><updated>2007-10-24T14:44:20.267-04:00</updated><title type='text'>Undoing transactions in a broken Plone/Zope</title><content type='html'>Today there was a situation where someone made a permission change that made Plone inaccessible.  The ZMI was also inaccessible (by design (not mine)). We could get access to the filesystem, however.  So after a couple attempts at undos through in debug....There were issues with permissions and RESPONSE objects and all the other Zope machinery. So I tried mounting a ZODB directly and undoing transactions. The following worked great for me:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;filename = "/Users/reedobrien/instances/zeo/msrd/var/Data.fs"&lt;br /&gt;import ZODB.FileStorage&lt;br /&gt;import ZODB.DB&lt;br /&gt;storage = ZODB.FileStorage.FileStorage(filename)&lt;br /&gt;DB = ZODB.DB(storage)&lt;br /&gt;txs = DB.undoLog()[::-1]&lt;br /&gt;DB.undo(id=txs[0]['id'])&lt;br /&gt;import transaction; transaction.commit()&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Maybe the wrong way and YMMV, but it stayed in one piece for me.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/33763744-1835724234761725475?l=reedobrien.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://reedobrien.blogspot.com/feeds/1835724234761725475/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=33763744&amp;postID=1835724234761725475' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/33763744/posts/default/1835724234761725475'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/33763744/posts/default/1835724234761725475'/><link rel='alternate' type='text/html' href='http://reedobrien.blogspot.com/2007/10/undoing-transactions-in-broken.html' title='Undoing transactions in a broken Plone/Zope'/><author><name>reedobrien</name><uri>http://www.blogger.com/profile/15835081896608317143</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-33763744.post-9123674859888979209</id><published>2007-08-14T10:26:00.000-04:00</published><updated>2007-08-14T10:29:05.078-04:00</updated><title type='text'>Passwordless Unix Login</title><content type='html'>&lt;h2&gt;Create a key pair&lt;/h2&gt;&lt;pre&gt;mack:~ reedobrien$ ssh-keygen -t rsa -f ~/.ssh/id_rsa&lt;br /&gt;Generating public/private rsa key pair.&lt;br /&gt;Enter passphrase (empty for no passphrase):&lt;br /&gt;Enter same passphrase again:&lt;br /&gt;Your identification has been saved in /Users/reedobrien/.ssh/id_rsa.&lt;br /&gt;Your public key has been saved in /Users/reedobrien/.ssh/id_rsa.pub.&lt;br /&gt;The key fingerprint is:&lt;br /&gt;bd:6c:18:e3:1a:46:5f:3d:d9:95:ed:82:6b:ea:6b:ec&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;h2&gt;Add the public Key to the server where you want to authenticate&lt;/h2&gt;&lt;pre&gt;mack:~ reedobrien$ scp ~/.ssh/id_rsa.pub username@remoteserver:~/.ssh/id_rsa.pub&lt;br /&gt;mack:~ reedobrien$ ssh -l username remoteserver&lt;br /&gt;password: ********&lt;br /&gt;remoteserver:~ username$ cat ~/.ssh/id_rsa.pub &amp;gt;&amp;gt; ~/.ssh/authorized_keys&lt;br /&gt;remoteserver:~ username$ exit&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;span style="font-style: italic;"&gt;NOTE: There are many more advanced features, configurations, identity management things that can be done not covered here.&lt;/span&gt;&lt;br /&gt;&lt;h2&gt;Test&lt;/h2&gt;&lt;br /&gt;&lt;pre&gt;mack:~ reedobrien$ ssh -l robrien remoteserver&lt;br /&gt;Last login: Mon Aug 13 22:28:10 2007 from 131.182.85.5&lt;br /&gt;Welcome to A Better World!&lt;br /&gt;remoteserver:~ robrien$&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/33763744-9123674859888979209?l=reedobrien.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://reedobrien.blogspot.com/feeds/9123674859888979209/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=33763744&amp;postID=9123674859888979209' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/33763744/posts/default/9123674859888979209'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/33763744/posts/default/9123674859888979209'/><link rel='alternate' type='text/html' href='http://reedobrien.blogspot.com/2007/08/passwordless-unix-login.html' title='Passwordless Unix Login'/><author><name>reedobrien</name><uri>http://www.blogger.com/profile/15835081896608317143</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-33763744.post-4208629217308196153</id><published>2007-08-02T23:32:00.000-04:00</published><updated>2007-08-03T00:33:06.718-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='debug'/><category scheme='http://www.blogger.com/atom/ns#' term='ipython'/><category scheme='http://www.blogger.com/atom/ns#' term='zope3'/><category scheme='http://www.blogger.com/atom/ns#' term='python'/><category scheme='http://www.blogger.com/atom/ns#' term='zope'/><title type='text'>ipython in zope3 zopectl debug</title><content type='html'>The solution in my earlier post doesn't fly in zope3. To get it to work in zope3 I modified:&lt;br /&gt;~/instances/z3/bin/debugzope&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;if __name__ == '__main__':    db = startup()&lt;br /&gt;     del startup&lt;br /&gt;     from zope.app.debug import Debugger&lt;br /&gt;     debugger = app = Debugger.fromDatabase(db)&lt;br /&gt;     root = app.root()&lt;br /&gt;     del db&lt;br /&gt;     del Debugger&lt;br /&gt;     &lt;span style="color: rgb(0, 102, 0);"&gt;import IPython&lt;/span&gt;&lt;br /&gt;     &lt;span style="color: rgb(0, 102, 0);"&gt;IPython.Shell.IPShell(user_ns={'root': root,&lt;br /&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 102, 0);"&gt;                                     'app': app,&lt;/span&gt;                         &lt;br /&gt;                           &lt;span style="color: rgb(0, 102, 0);"&gt;         'top' : app.root() &lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 102, 0);"&gt;                                     &lt;/span&gt;&lt;span style="color: rgb(0, 102, 0);"&gt;}).mainloop(sys_exit=1)&lt;/span&gt;&lt;/pre&gt;&lt;span style="color: rgb(0, 102, 0);"&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;I haven't figured out much about how the debugger differs in Zope3.  But it gives me top as app.root().&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;In [1]: print top.items()&lt;br /&gt;&amp;lt;OOBTreeItems object at 0x355c598&amp;gt;&lt;br /&gt;&lt;br /&gt;In [2]: app.root()['foo']&lt;br /&gt;Out[2]: &amp;lt;zope.app.folder.folder.Folder object at 0x36dfef0&amp;gt;&lt;br /&gt;&lt;br /&gt;In [3]: top&lt;br /&gt;Out[3]: &amp;lt;zope.app.folder.folder.Folder object at 0x36a27f0&amp;gt;&lt;br /&gt;&lt;br /&gt;In [4]: top['foo']&lt;br /&gt;Out[4]: &amp;lt;zope.app.folder.folder.Folder object at 0x36df830&amp;gt;&lt;br /&gt;&lt;br /&gt;In [5]: print [x for x in top.items()]&lt;br /&gt;[(u'foo', &amp;lt;zope.app.folder.folder.Folder object at 0x36df830&amp;gt;)]&lt;oobtreeitems&gt;&lt;zope.app.folder.folder.folder&gt;&lt;zope.app.folder.folder.folder&gt;&lt;zope.app.folder.folder.folder&gt;&lt;zope.app.folder.folder.folder&gt;&lt;oobtreeitems&gt;&lt;zope.app.folder.folder.folder&gt;&lt;zope.app.folder.folder.folder&gt;&lt;zope.app.folder.folder.folder&gt;&lt;zope.app.folder.folder.folder&gt;&lt;/zope.app.folder.folder.folder&gt;&lt;/zope.app.folder.folder.folder&gt;&lt;/zope.app.folder.folder.folder&gt;&lt;/zope.app.folder.folder.folder&gt;&lt;/oobtreeitems&gt;&lt;/zope.app.folder.folder.folder&gt;&lt;/zope.app.folder.folder.folder&gt;&lt;/zope.app.folder.folder.folder&gt;&lt;/zope.app.folder.folder.folder&gt;&lt;/oobtreeitems&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/33763744-4208629217308196153?l=reedobrien.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://reedobrien.blogspot.com/feeds/4208629217308196153/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=33763744&amp;postID=4208629217308196153' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/33763744/posts/default/4208629217308196153'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/33763744/posts/default/4208629217308196153'/><link rel='alternate' type='text/html' href='http://reedobrien.blogspot.com/2007/08/ipython-in-zope3-zopectl-debug.html' title='ipython in zope3 zopectl debug'/><author><name>reedobrien</name><uri>http://www.blogger.com/profile/15835081896608317143</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-33763744.post-6520023940470619732</id><published>2007-07-01T15:56:00.000-04:00</published><updated>2008-02-11T17:19:49.173-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='debug'/><category scheme='http://www.blogger.com/atom/ns#' term='ipython'/><category scheme='http://www.blogger.com/atom/ns#' term='python'/><category scheme='http://www.blogger.com/atom/ns#' term='plone'/><category scheme='http://www.blogger.com/atom/ns#' term='zope'/><title type='text'>ipython in zopectl debug</title><content type='html'>A long time ago (6mos? a year) I got tired of manually typing support for history and tab completion into the zope debugger. So I just hooked the debug command up to read my .pythonrc file by importing user in the do_debug method  of zopectl.py.&lt;pre&gt;def do_debug(self, arg):&lt;br /&gt;   cmdline = self.get_startup_cmd(self.options.python + ' -i',&lt;br /&gt;   "import Zope2; app=Zope2.app(); import user;")&lt;/pre&gt;Today I tried getting ipython working as described in the &lt;a href="http://plone.org/documentation/how-to/setup-ipython-for-zope"&gt;plone docs.&lt;/a&gt; I also tried &lt;a href="http://vanrees.org/weblog/topics/sorrentosprint2007"&gt;vanrees notes&lt;/a&gt;&lt;div&gt; and a couple others. I could not get it going though. So I decided to return to the hack above and extend it to load ipython.&lt;/div&gt;&lt;pre&gt;def do_debug(self, arg):&lt;br /&gt;    cmdline = self.get_startup_cmd(self.options.python + ' -i',&lt;br /&gt;    "import Zope2; app=Zope2.app(); import user;     &lt;br /&gt;     ns={'__name__':'msrd','app':app}; import IPython;   &lt;br /&gt;     IPython.Shell.IPShell(user_ns=ns).mainloop(sys_exit=1);")&lt;/pre&gt;Poof, now debug comes up with ipython. Yay... What does that mean you may ask?&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;blockquote&gt;&lt;plonesite at="" msrd=""&gt;In [2]: ??app.msrd&lt;br /&gt;Type:           ImplicitAcquirerWrapper&lt;br /&gt;Base Class:     &lt;class&gt;&lt;br /&gt;String Form:    &lt;plonesite at="" msrd=""&gt;&lt;br /&gt;Namespace:      Interactive&lt;br /&gt;Length:         1&lt;br /&gt;Docstring [source file open failed]:&lt;br /&gt;Make PloneSite subclass CMFSite and add some methods.&lt;br /&gt;This will be useful for adding more things later on.&lt;br /&gt;&lt;/plonesite&gt;&lt;/class&gt;&lt;/plonesite&gt;&lt;/blockquote&gt;&lt;div&gt;I know this is probably the wrong way to do this, but nyah nyah. It is working now.  I do welcome feedback...&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;div&gt;As a note: I also have import user in my args.  This picks up stuff from your file defined in PYTHONSTARTUP.  But then if you already use PYTHONSTARTUP you probably already know that.&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/33763744-6520023940470619732?l=reedobrien.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://reedobrien.blogspot.com/feeds/6520023940470619732/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=33763744&amp;postID=6520023940470619732' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/33763744/posts/default/6520023940470619732'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/33763744/posts/default/6520023940470619732'/><link rel='alternate' type='text/html' href='http://reedobrien.blogspot.com/2007/07/ipython-in-zopectl-debug.html' title='ipython in zopectl debug'/><author><name>reedobrien</name><uri>http://www.blogger.com/profile/15835081896608317143</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-33763744.post-3638868497246192123</id><published>2007-01-19T20:23:00.000-05:00</published><updated>2007-01-19T21:30:22.106-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='python'/><category scheme='http://www.blogger.com/atom/ns#' term='zodb'/><category scheme='http://www.blogger.com/atom/ns#' term='plone'/><category scheme='http://www.blogger.com/atom/ns#' term='zope'/><title type='text'>Plone site broken? Fix ir through the zodb</title><content type='html'>Today someone changed the ip on a dev box running an instance that had the ip as part of the url in CacheFu. So of course it won't load a page anymore.  What to do? reinstall? nah.  Let 's think for a second.  Plone is a nice interface to  Zope/CMF.  Zope/CMF is a lovely interface to ZODB.  ZODB is a persistence engine for Python objects. CacheFu's settings are persisted as atributes of a cache object in the ZODB. Let's just fix it directly....&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;/usr/local/{instance}&lt;instance&gt;/bin/zopectl debug&lt;br /&gt;Starting debugger (the name "app" is bound to the top-level Zope object)&lt;br /&gt;...{  8&lt; snip } ...&lt;br /&gt;&gt;&gt;&gt; import readline, rlcompleter, transaction&lt;br /&gt;&gt;&gt;&gt; readline.parse_and_bind("tab: complete")&lt;br /&gt;&lt;span style="color: rgb(0, 153, 0);"&gt;# now we have tab completion&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 153, 0);"&gt;# bind the plone root to s&lt;/span&gt;&lt;br /&gt;&gt;&gt;&gt; s = app.itcd&lt;br /&gt;&lt;span style="color: rgb(0, 153, 0);"&gt;# bind our (s)ites cache settings to cc&lt;/span&gt;&lt;br /&gt;&gt;&gt;&gt; cc = s.portal_cache_settings&lt;br /&gt;&gt;&gt;&gt; cc.getDomains()&lt;br /&gt;('http://1.2.3.4:80',)  &lt;span style="color: rgb(0, 153, 0);"&gt;## &lt;&lt;== look there is our old value!!&lt;/span&gt;&lt;br /&gt;# yup it needs to be this new value&lt;br /&gt;&gt;&gt;&gt; cc.setDomains("http://4.3.2.1:8080")&lt;br /&gt;&lt;span style="color: rgb(0, 153, 0);"&gt;# and persisted. Otherwise it will be aborted at exit&lt;/span&gt;&lt;br /&gt;&gt;&gt;&gt; transaction.commit() &lt;/instance&gt;&lt;/blockquote&gt;&lt;br /&gt;That was easy, no?&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/33763744-3638868497246192123?l=reedobrien.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://reedobrien.blogspot.com/feeds/3638868497246192123/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=33763744&amp;postID=3638868497246192123' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/33763744/posts/default/3638868497246192123'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/33763744/posts/default/3638868497246192123'/><link rel='alternate' type='text/html' href='http://reedobrien.blogspot.com/2007/01/plone-site-broken-fix-ir-through-zodb.html' title='Plone site broken? Fix ir through the zodb'/><author><name>reedobrien</name><uri>http://www.blogger.com/profile/15835081896608317143</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-33763744.post-2987230425697660785</id><published>2007-01-05T19:51:00.000-05:00</published><updated>2007-01-05T20:10:08.960-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='freebsd'/><category scheme='http://www.blogger.com/atom/ns#' term='spam'/><category scheme='http://www.blogger.com/atom/ns#' term='python'/><title type='text'>Quick and dirty regexen search for spamd &amp; postfix logs</title><content type='html'>&lt;pre&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 153, 0);"&gt;#!/usr/bin/env python&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 153, 0);"&gt;#-------------------------------------------------------------&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 153, 0);"&gt;# Name:        finder.py&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 153, 0);"&gt;# Purpose:     This is a script to search through  Posfix &lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 153, 0);"&gt;#              and spamd logs for the last x days and return &lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 153, 0);"&gt;#              hits. Mostly it is a quick and dirty way to &lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 153, 0);"&gt;#              find entris regarding emails blocked by &lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 153, 0);"&gt;#              spamd/postfix   &lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 153, 0);"&gt;# Author:      Reed L. O'Brien reed at reedobrien com&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 153, 0);"&gt;#                                                                                                           &lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 153, 0);"&gt;# Created:     2007-01-05&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 153, 0);"&gt;# Modified:    2007-01-05&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 153, 0);"&gt;# Copyright:   (c) Reed L. O'Brien 2007&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 153, 0);"&gt;# License:     DWYWWI (improvements welcome)                         &lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 153, 0);"&gt;#--------------------------------------------------------------                      &lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 153, 0);"&gt;#Do the imports&lt;/span&gt;&lt;br /&gt;import os, re, bz2, sys, time&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 153, 0);"&gt;# make sure there is a regex&lt;/span&gt;&lt;br /&gt;try:&lt;br /&gt;&lt;span style="color: rgb(0, 153, 0);"&gt;    # compile the regex&lt;/span&gt;&lt;br /&gt;  regx = re.compile(sys.argv[1], re.IGNORECASE)&lt;br /&gt;except IndexError:&lt;br /&gt;  print """&lt;br /&gt;  usage:&lt;br /&gt;         finder &lt;exp&gt; [days back to search]&lt;br /&gt;&lt;br /&gt;         ex: finder foobar 2&lt;br /&gt;         will find all occurences of 'foobar' in the last 2&lt;br /&gt;         days of spamd and maillog files.\n\tThe number of days&lt;br /&gt;         is optional and defaults to 1 if not given."""&lt;br /&gt;  sys.exit(0)&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 153, 0);"&gt;# empty list to store hits in&lt;/span&gt;&lt;br /&gt;found = []&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 153, 0);"&gt;# move to the log directory&lt;/span&gt;&lt;br /&gt;os.chdir('/var/log')&lt;br /&gt;&lt;span style="color: rgb(0, 153, 0);"&gt;# Start a counter for the number counted&lt;/span&gt;&lt;br /&gt;s = 0&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 153, 0);"&gt;#get and set days&lt;/span&gt;&lt;br /&gt;try:&lt;br /&gt; days = int(sys.argv[2])&lt;br /&gt;except:&lt;br /&gt; days = 1&lt;br /&gt;&lt;span style="color: rgb(0, 153, 0);"&gt;# Get a list of qualifying files NOTE: you may need stat(x).[st_ctime|st_mtime] depending on your OS&lt;/span&gt;&lt;br /&gt;L = [f for f in os.listdir('.')&lt;br /&gt;   if os.stat(f).st_birthtime &gt; time.time() - (days * 86400)&lt;br /&gt;   and (f.startswith('spamd') or f.startswith('maillog'))]&lt;br /&gt;&lt;span style="color: rgb(0, 153, 0);"&gt;# get a count of how many files to search&lt;/span&gt;&lt;br /&gt;n = len(L)&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 153, 0);"&gt;# start a loop on the list&lt;/span&gt;&lt;br /&gt;for f in L:&lt;br /&gt;&lt;span style="color: rgb(0, 153, 0);"&gt;    # If it is a bz2 open it as a bz2 object&lt;/span&gt;&lt;br /&gt;if (f.startswith('spamd') or f.startswith('maillog')) and f.endswith('2'):&lt;br /&gt;&lt;span style="color: rgb(0, 153, 0);"&gt; # tell em what is happening&lt;/span&gt;&lt;br /&gt;   sys.stdout.write("\rsearching: %2s  remain %s                   " % (f,n))&lt;br /&gt;   sys.stdout.flush()&lt;br /&gt;&lt;span style="color: rgb(0, 153, 0);"&gt;        # set a line count&lt;/span&gt;&lt;br /&gt;   c = 1&lt;br /&gt;&lt;span style="color: rgb(0, 153, 0);"&gt;        # get a handle on the file&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 153, 0);"&gt; &lt;/span&gt;       handle = bz2.BZ2File(f)&lt;br /&gt;&lt;span style="color: rgb(0, 153, 0);"&gt;        # iterate through the lines&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 153, 0);"&gt; &lt;/span&gt;       for line in handle:&lt;br /&gt;&lt;span style="color: rgb(0, 153, 0);"&gt;        # if the regex is found&lt;/span&gt;&lt;br /&gt;       if regx.search(line):&lt;span style="color: rgb(0, 153, 0);"&gt;&lt;br /&gt;           # append the filename, line count and line content to the found list&lt;/span&gt;&lt;br /&gt;           found.append("%-10s : %s\n%s" % (c, f, line))&lt;br /&gt;&lt;span style="color: rgb(0, 153, 0);"&gt;                # increment the line count&lt;/span&gt;&lt;br /&gt;           c += 1&lt;br /&gt;       else:&lt;br /&gt;       &lt;span style="color: rgb(0, 153, 0);"&gt;    # or just increment the count if no regex match &lt;/span&gt;&lt;br /&gt;           c += 1&lt;br /&gt;&lt;span style="color: rgb(0, 153, 0);"&gt;                # decrement the number of files remaining&lt;/span&gt;&lt;br /&gt;           n -= 1  &lt;br /&gt;&lt;span style="color: rgb(0, 153, 0);"&gt;                # increment the number of files searched&lt;/span&gt;&lt;br /&gt;           s += 1&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 153, 0);"&gt;    ## DO the same as above as a regular file object if not a bz2 file SEE NOTES FOR last loop&lt;/span&gt;&lt;br /&gt;if (f.startswith('spamd') or f.startswith('maillog')) and not f.endswith('2'):&lt;br /&gt;   sys.stdout.write("\rsearching: %2s  remain %s                     " % (f,n))&lt;br /&gt;   sys.stdout.flush()&lt;br /&gt;   c = 1&lt;br /&gt;   handle = open(f)&lt;br /&gt;   for line in handle:&lt;br /&gt;       if regx.search(line):&lt;br /&gt;           found.append("%-10s : %s\n%s" % (c, f, line))&lt;br /&gt;           c += 1&lt;br /&gt;       else:&lt;br /&gt;           c += 1&lt;br /&gt;           n -= 1&lt;br /&gt;           s += 1&lt;br /&gt;&lt;span style="color: rgb(0, 153, 0);"&gt;                ##make some space to overwrite the sys.stdout text &lt;/span&gt;&lt;br /&gt;print '\n\n\n\n\n'&lt;br /&gt;print 'Searched:', s # Print how many files were searched&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 153, 0);"&gt;#print the results from the found list.&lt;/span&gt;&lt;br /&gt;for x in found:&lt;br /&gt;print x&lt;br /&gt;&lt;/exp&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/33763744-2987230425697660785?l=reedobrien.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://reedobrien.blogspot.com/feeds/2987230425697660785/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=33763744&amp;postID=2987230425697660785' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/33763744/posts/default/2987230425697660785'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/33763744/posts/default/2987230425697660785'/><link rel='alternate' type='text/html' href='http://reedobrien.blogspot.com/2007/01/quick-and-dirty-searches-for-regexen-in.html' title='Quick and dirty regexen search for spamd &amp; postfix logs'/><author><name>reedobrien</name><uri>http://www.blogger.com/profile/15835081896608317143</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-33763744.post-116733161930836620</id><published>2006-12-28T13:46:00.000-05:00</published><updated>2006-12-28T17:28:22.387-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='python'/><title type='text'>Mostly functional email regex</title><content type='html'>&lt;pre wrap=""&gt;for word based delims in text:&lt;br /&gt;em = re.compile(r&lt;a class="moz-txt-link-rfc2396E" href="mailto:%5Cb%5B%27A-Z0-9._%-%5D+@%5BA-Z0-9.-%5D+%5C.%5BA-Z%5D%7B2,4%7D%5Cb"&gt;"\b['A-Z0-9._%-]+@[A-Z0-9.-]+\.[A-Z]{2,4}\b"&lt;/a&gt;,&lt;br /&gt;   re.IGNORECASE)&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;for start and endline delims:&lt;br /&gt;em = re.compile(r&lt;a class="moz-txt-link-rfc2396E" href="mailto:%5E%5B%27A-Z0-9._%-%5D+@%5BA-Z0-9.-%5D+%5C.%5BA-Z%5D%7B2,4%7D$"&gt;"^['A-Z0-9._%-]+@[A-Z0-9.-]+\.[A-Z]{2,4}$"&lt;/a&gt;,&lt;br /&gt;    re.IGNORECASE)&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/33763744-116733161930836620?l=reedobrien.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://reedobrien.blogspot.com/feeds/116733161930836620/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=33763744&amp;postID=116733161930836620' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/33763744/posts/default/116733161930836620'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/33763744/posts/default/116733161930836620'/><link rel='alternate' type='text/html' href='http://reedobrien.blogspot.com/2006/12/mostly-functional-email-regex.html' title='Mostly functional email regex'/><author><name>reedobrien</name><uri>http://www.blogger.com/profile/15835081896608317143</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-33763744.post-116613815272485568</id><published>2006-12-14T15:02:00.000-05:00</published><updated>2007-08-08T12:50:47.196-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='freebsd'/><category scheme='http://www.blogger.com/atom/ns#' term='spam'/><title type='text'>less spam with spamd and pf</title><content type='html'>&lt;span&gt;&lt;span style="color: rgb(0, 102, 0);"&gt;&lt;span style="font-weight: bold;"&gt;untested but should be pretty close&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-style: italic;"&gt;##Assumes Freebsd built with postfix and pf:&lt;/span&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;##requires  spamd&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-style: italic; color: rgb(0, 102, 0);"&gt;#Add line to /etc/fstab&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;# Device             Mountpoint      FStype Options   Dump  Pass&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;fdescfs                 /dev/fd         fdecfs  rw              0       0&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 102, 0);"&gt;# mount it&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="font-weight: bold;"&gt;sudo mount -a&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-style: italic; color: rgb(0, 102, 0);"&gt;## build spamd&lt;/span&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;cd /usr/ports/mail/spamd &amp;&amp;amp; sudo make install&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="font-style: italic; color: rgb(0, 102, 0);"&gt;#answer yes&lt;/span&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;This system has no entry for spamd in /etc/services&lt;/span&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;Would you like to add it automatically? (y/n) [y]?&lt;/span&gt;&lt;span style="font-weight: bold;"&gt; y&lt;br /&gt;&lt;/span&gt;&lt;span style="font-style: italic;"&gt;This system has no entry for spamd-cfg in /etc/services&lt;/span&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;Would you like to add it automatically? (y/n) [y]?&lt;/span&gt;&lt;span style="font-weight: bold;"&gt; y&lt;br /&gt;&lt;/span&gt;&lt;span style="font-style: italic;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="font-style: italic;"&gt;&lt;span style="color: rgb(0, 102, 0);"&gt;&lt;br /&gt;# setup spamd.conf&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;all:\&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;    :spamhaus:spamhausDROP:whitelist:spews1:spews2:china:korea:becks:blacklist:&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;# Mirrored from http://spfilter.openrbl.org/data/sbl/SBL.cidr.bz2&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;spamhaus:\&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;    :black:\&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;    :msg="SPAM. Your address %A is in the Spamhaus Block List\n\&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;    See http://www.spamhaus.org/sbl and\&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;    http://www.abuse.net/sbl.phtml?IP=%A for more details":\&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;    :method=http:\&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;    :file=www.openbsd.org/spamd/SBL.cidr.gz:&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;spamhausDROP:\&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;    :black:\&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;    :msg="SPAM. Your address %A is in the Spamhaus DROP List\n\&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;    See http://www.spamhaus.org/sbl and\&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;    http://www.abuse.net/sbl.phtml?IP=%A for more details":\&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;    :method=http:\&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;    :file=www.spamhaus.org/DROP/drop.lasso:&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;becks:\ &lt;span style="color: rgb(255, 0, 0); font-style: italic;"&gt;# experimental, probably blocks some good ips &lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;        :black:\&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;        :msg="SPAM. Your address %A has sent spam within the last 24 hours":\&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;        :method=http:\&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;        :file=www.openbsd.org/spamd/traplist.gz&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;# Mirrored from http://www.spews.org/spews_list_level1.txt&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;spews1:\&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;    :black:\&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;    :msg="SPAM. Your address %A is in the spews level 1 database\n\&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;    See http://www.spews.org/ask.cgi?x=%A for more details":\&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;    :method=http:\&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;    :file=www.openbsd.org/spamd/spews_list_level1.txt.gz:&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;# Mirrored from http://www.spews.org/spews_list_level2.txt&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;spews2:\&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;    :black:\&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;    :msg="SPAM. Your address %A is in the spews level 2 database\n\&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;    See http://www.spews.org/ask.cgi?x=%A for more details":\&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;    :method=http:\&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;    :file=www.openbsd.org/spamd/spews_list_level2.txt.gz:&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;# Mirrored from http://www.okean.com/chinacidr.txt&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;china:\&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;    :black:\&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;    :msg="SPAM. Your address %A appears to be from China\n\&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;    See http://www.okean.com/asianspamblocks.html for more details":\&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;    :method=http:\&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;    :file=www.openbsd.org/spamd/chinacidr.txt.gz:&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;# Mirrored from http://www.okean.com/koreacidr.txt&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;korea:\&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;    :black:\&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;    :msg="SPAM. Your address %A appears to be from Korea\n\&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;    See http://www.okean.com/asianspamblocks.html for more details":\&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;    :method=http:\&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;    :file=www.openbsd.org/spamd/koreacidr.txt.gz:&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;# Whitelists are done like this, and must be added to "all" after each&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;# blacklist from which you want the addresses in the whitelist removed.&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;#&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;whitelist:\&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;    :white:\&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;    :file=/var/mail/whitelist.txt:&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;blacklist:\&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;    :black:\&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;    :msg=/var/mail/blackmsg.txt:\&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;    :method=file:\&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;    :file=/var/mail/blacklist.txt:&lt;/span&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 102, 0);"&gt;# touch the spamd and chown it&lt;span style="font-weight: bold;"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-weight: bold;"&gt;&lt;br /&gt;sudo touch /var/db/spamd &amp;&amp;amp; sudo chown nobody:wheel /var/db/spamd&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 102, 0);"&gt;#create the inital log file&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;sudo touch /var/log/spamd&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;# make spamd log in it's own log in /etc/syslog.conf&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;!spamd&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;*.*                                             /var/log/spamd&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 102, 0);"&gt;#restart it&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0); font-weight: bold;"&gt;sudo /etc/rc.d/syslogd restart&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;# make it rotate IN /etc/newsyslog.conf&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-style: italic; color: rgb(0, 0, 0);"&gt;&lt;/span&gt;&lt;span style="font-weight: bold; color: rgb(0, 0, 0);"&gt;&lt;/span&gt;/var/log/spamd                          640  1000       *       @T00  JC&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 102, 0);"&gt;#edit pf.conf&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;# macros&lt;br /&gt;nic = "xl0"&lt;br /&gt;&lt;br /&gt;tcp_services = "{ 22, 25, 8080}"&lt;br /&gt;icmp_types = "echoreq"&lt;br /&gt;udp_services = "{ 123, 53 }"&lt;br /&gt;web_service = "{ 80 }"&lt;br /&gt;mail_host = "127.0.0.1"&lt;br /&gt;&lt;br /&gt;priv_nets = "{ 127.0.0.0/8, 172.16.0.0/12, 10.0.0.0/8 }"&lt;br /&gt;my_nets = "{ 192.168.68.0/24}"&lt;br /&gt;&lt;br /&gt;# options&lt;br /&gt;set block-policy return&lt;br /&gt;set loginterface $nic&lt;br /&gt;set skip on lo0&lt;br /&gt;&lt;br /&gt;# scrub&lt;br /&gt;scrub in all&lt;br /&gt;&lt;br /&gt;#########&lt;br /&gt;## Spamd&lt;br /&gt;#########&lt;br /&gt;&lt;br /&gt;# grey  host list&lt;br /&gt;table &lt;spamd&gt; persist&lt;br /&gt;&lt;br /&gt;#white host list&lt;br /&gt;table &lt;spamd-white&gt; persist&lt;br /&gt;table &lt;spamd-mywhite&gt; persist file "/var/mail/whitelist.txt"&lt;br /&gt;&lt;br /&gt;# forward white listed ips&lt;br /&gt;rdr pass on $nic inet proto tcp from &lt;spamd&gt; to        $nic port smtp -&gt; 127.0.0.1 port 8025&lt;br /&gt;&lt;br /&gt;rdr pass on $nic proto tcp from &lt;spamd-mywhite&gt; to       $nic port smtp -&gt; $mail_host port smtp&lt;br /&gt;&lt;br /&gt;rdr pass on $nic proto tcp from &lt;spamd-white&gt; to       $nic port smtp -&gt; $mail_host port smtp&lt;br /&gt;&lt;br /&gt;# send all suspects to the spamd daemon&lt;br /&gt;&lt;br /&gt;rdr pass on $nic inet proto tcp from !&lt;spamd-white&gt; to        $nic port smtp -&gt; 127.0.0.1 port 8025&lt;br /&gt;&lt;br /&gt;rdr pass on $nic inet proto tcp       from any to $nic port smtp -&gt; $mail_host port smtp&lt;br /&gt;&lt;br /&gt;# filter rules&lt;br /&gt;block all&lt;br /&gt;&lt;br /&gt;block drop in quick on $nic from $priv_nets to any&lt;br /&gt;block drop out quick on $nic from any to $priv_nets&lt;br /&gt;&lt;br /&gt;pass in on $nic inet proto tcp from any to $nic  port smtp flags S/SA keep state&lt;br /&gt;&lt;br /&gt;pass in on $nic inet proto tcp from $my_nets to $nic  port $tcp_services flags S/SA keep state&lt;br /&gt;&lt;br /&gt;pass in on $nic inet proto tcp from any to $nic  port $web_service flags S/SA keep state&lt;br /&gt;&lt;br /&gt;pass in on $nic inet proto udp from any to $nic  port $udp_services&lt;br /&gt;&lt;br /&gt;pass in on $nic inet proto udp from any to $nic port 123&lt;br /&gt;&lt;br /&gt;pass in inet proto icmp all icmp-type $icmp_types keep state&lt;br /&gt;&lt;br /&gt;pass out on $nic proto tcp all modulate state flags S/SA&lt;br /&gt;pass out on $nic proto { udp, icmp } all keep state&lt;br /&gt;&lt;br /&gt;#make /var/mail/whitelist.txt&lt;br /&gt;#FDS&lt;br /&gt;192.251.225.192/26&lt;br /&gt;#apple&lt;br /&gt;17.0.0.0/8&lt;br /&gt;#aol.com&lt;br /&gt;152.163.225.0/24&lt;br /&gt;205.188.139.0/24&lt;br /&gt;205.188.144.0/24&lt;br /&gt;205.188.156.0/23&lt;br /&gt;205.188.159.0/24&lt;br /&gt;64.12.136.0/23&lt;br /&gt;64.12.138.0/24&lt;br /&gt;152.163.225.0/24&lt;br /&gt;205.188.139.0/24&lt;br /&gt;205.188.144.0/24&lt;br /&gt;205.188.156.0/23&lt;br /&gt;205.188.159.0/24&lt;br /&gt;64.12.136.0/23&lt;br /&gt;64.12.138.0/24&lt;br /&gt;#amazon.com&lt;br /&gt;207.171.160.0/19&lt;br /&gt;87.238.80.0/21&lt;br /&gt;72.21.196.0/24&lt;br /&gt;72.21.208.0/24&lt;br /&gt;207.171.160.32/28&lt;br /&gt;207.171.180.176/28&lt;br /&gt;207.171.164.32/28&lt;br /&gt;207.171.190.0/28&lt;br /&gt;87.238.80.24/29&lt;br /&gt;87.238.84.24/29&lt;br /&gt;72.21.196.0/24&lt;br /&gt;72.21.208.0/24&lt;br /&gt;#_spf.google.com&lt;br /&gt;216.239.56.0/23&lt;br /&gt;64.233.160.0/19&lt;br /&gt;66.249.80.0/20&lt;br /&gt;72.14.192.0/18&lt;br /&gt;#spf-a.hotmail.com&lt;br /&gt;209.240.192.0/19&lt;br /&gt;65.52.0.0/14&lt;br /&gt;131.107.0.0/16&lt;br /&gt;157.54.0.0/15&lt;br /&gt;157.56.0.0/14&lt;br /&gt;157.60.0.0/16&lt;br /&gt;167.220.0.0/16&lt;br /&gt;204.79.135.0/24&lt;br /&gt;204.79.188.0/24&lt;br /&gt;204.79.252.0/24&lt;br /&gt;207.46.0.0/16&lt;br /&gt;199.2.137.0/24&lt;br /&gt;#spf-b.hotmail.com&lt;br /&gt;199.103.90.0/23&lt;br /&gt;204.182.144.0/24&lt;br /&gt;204.255.244.0/23&lt;br /&gt;206.138.168.0/21&lt;br /&gt;64.4.0.0/18&lt;br /&gt;65.54.128.0/17&lt;br /&gt;207.68.128.0/18&lt;br /&gt;207.68.192.0/20&lt;br /&gt;207.82.250.0/23&lt;br /&gt;207.82.252.0/23&lt;br /&gt;209.1.112.0/23&lt;br /&gt;#spf-c.hotmail.com&lt;br /&gt;209.185.128.0/23&lt;br /&gt;209.185.130.0/23&lt;br /&gt;209.185.240.0/22&lt;br /&gt;216.32.180.0/22&lt;br /&gt;216.32.240.0/22&lt;br /&gt;216.33.148.0/22&lt;br /&gt;216.33.151.0/24&lt;br /&gt;216.33.236.0/22&lt;br /&gt;216.33.240.0/22&lt;br /&gt;216.200.206.0/24&lt;br /&gt;204.95.96.0/20&lt;br /&gt;#spf-d.hotmail.com&lt;br /&gt;65.59.232.0/23&lt;br /&gt;65.59.234.0/24&lt;br /&gt;209.1.15.0/24&lt;br /&gt;64.41.193.0/24&lt;br /&gt;216.34.51.0/24&lt;br /&gt;#_spf-a.microsoft.com&lt;br /&gt;213.199.128.139&lt;br /&gt;213.199.128.145&lt;br /&gt;207.46.50.72&lt;br /&gt;207.46.50.82&lt;br /&gt;#_spf-b.microsoft.com&lt;br /&gt;131.107.65.22&lt;br /&gt;131.107.65.131&lt;br /&gt;131.107.1.101&lt;br /&gt;131.107.1.102&lt;br /&gt;217.77.141.52&lt;br /&gt;217.77.141.59&lt;br /&gt;#_spf-c.microsoft.com&lt;br /&gt;131.107.1.18&lt;br /&gt;131.107.1.19&lt;br /&gt;131.107.1.20&lt;br /&gt;131.107.70.12&lt;br /&gt;131.107.70.16&lt;br /&gt;#s._spf.ebay.com.&lt;br /&gt;66.135.209.192/27&lt;br /&gt;66.135.197.0/27&lt;br /&gt;64.4.240.64/27&lt;br /&gt;64.4.244.64/27&lt;br /&gt;#m._spf.ebay.com&lt;br /&gt;66.135.215.224/27&lt;br /&gt;216.33.244.96/27&lt;br /&gt;216.33.244.84&lt;br /&gt;#p._spf.ebay.com&lt;br /&gt;67.72.99.26&lt;br /&gt;206.165.246.83&lt;br /&gt;206.165.246.84&lt;br /&gt;206.165.246.85&lt;br /&gt;206.165.246.86&lt;br /&gt;64.127.115.252&lt;br /&gt;194.64.234.129/27&lt;br /&gt;#c._spf.ebay.com&lt;br /&gt;12.155.144.75&lt;br /&gt;62.22.61.131&lt;br /&gt;63.104.149.126&lt;br /&gt;64.68.79.253&lt;br /&gt;64.94.204.222&lt;br /&gt;66.135.215.134&lt;br /&gt;67.72.12.29&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 102, 0);"&gt;#make /var/mail/blacklist.txt&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;1.2.3.4 My-black&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;/spamd-white&gt;&lt;/spamd-white&gt;&lt;/spamd-mywhite&gt;&lt;/spamd&gt;&lt;/spamd-mywhite&gt;&lt;/spamd-white&gt;&lt;/spamd&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 102, 0);"&gt;#make /var/mail/blackmsg.txt&lt;br /&gt;&lt;/span&gt;SPAM. Your address %A is in my blacklist&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 102, 0);"&gt;# in postfix main.cf&lt;/span&gt;&lt;br /&gt;strict_rfc821_envelopes = yes&lt;br /&gt;smtpd_helo_required = yes&lt;br /&gt;smtpd_delay_reject = yes&lt;br /&gt;&lt;br /&gt;smtpd_recipient_restrictions =&lt;br /&gt; warn_if_reject reject_unknown_client,&lt;br /&gt; reject_invalid_hostname,&lt;br /&gt; reject_non_fqdn_hostname,&lt;br /&gt; reject_non_fqdn_sender,&lt;br /&gt; reject_non_fqdn_recipient,&lt;br /&gt; reject_unknown_sender_domain,&lt;br /&gt; reject_unknown_recipient_domain,&lt;br /&gt; permit_mynetworks,&lt;br /&gt; reject_unauth_destination,&lt;br /&gt; reject_rhsbl_sender dsn.rfc-ignorant.org&lt;br /&gt; reject_rhsbl_sender bogusmx.rfc-ignorant.org,&lt;br /&gt; reject_rbl_client bl.spamcop.net,&lt;br /&gt; reject_rbl_client sbl-xbl.spamhaus.org,&lt;br /&gt; reject_rbl_client dnsbl.sorbs.net,&lt;br /&gt; reject_rbl_client list.dsbl.org&lt;br /&gt; reject_rbl_client relays.ordb.org,&lt;br /&gt; permit&lt;br /&gt;&lt;br /&gt;smtpd_data_restrictions =&lt;br /&gt; reject_unauth_pipelining,&lt;br /&gt; permit&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;relay_domains = $mydestination /usr/local/etc/postfix/relay_domains.txt&lt;br /&gt;smtp_recipient_restrictions = permit_mynetworks reject_unauth_destination&lt;br /&gt;relay_recipient_maps = hash:/usr/local/etc/postfix/relay_recipients&lt;br /&gt;transport_maps = hash:/usr/local/etc/postfix/transport&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 102, 0);"&gt;#/usr/local/etc/postfix/relay_domains.txt&lt;/span&gt;&lt;br /&gt;example.com&lt;br /&gt;another.net&lt;br /&gt;three.org&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 102, 0);"&gt;#/usr/local/etc/postfix/relay_recipients&lt;/span&gt;&lt;br /&gt;@example.com x&lt;br /&gt;@another.net x&lt;br /&gt;justme@three.org x&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 102, 0);"&gt;#/usr/local/etc/postfix/transport&lt;/span&gt;&lt;br /&gt;example.com relay:[mail.example.com]&lt;br /&gt;another.net relay:[mail.example.com]&lt;br /&gt;three.org relay:[mail.three.org]&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 102, 0);"&gt;#do&lt;/span&gt;&lt;br /&gt;sudo postmap /usr/local/etc/postfix/relay_recipients&lt;br /&gt;sudo postmap /usr/local/etc/postfix/transports&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 102, 0);"&gt;#put spamd into rc.conf&lt;/span&gt;&lt;br /&gt;pfspamd_enable="YES"&lt;br /&gt;pfspamd_flags="-v -4 -g -G25:4:864 -s10"&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/33763744-116613815272485568?l=reedobrien.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://reedobrien.blogspot.com/feeds/116613815272485568/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=33763744&amp;postID=116613815272485568' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/33763744/posts/default/116613815272485568'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/33763744/posts/default/116613815272485568'/><link rel='alternate' type='text/html' href='http://reedobrien.blogspot.com/2006/12/less-spam.html' title='less spam with spamd and pf'/><author><name>reedobrien</name><uri>http://www.blogger.com/profile/15835081896608317143</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-33763744.post-115722507482974992</id><published>2006-09-02T15:23:00.000-04:00</published><updated>2006-09-02T15:25:31.950-04:00</updated><title type='text'>First Post</title><content type='html'>Great more data smog.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/33763744-115722507482974992?l=reedobrien.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://reedobrien.blogspot.com/feeds/115722507482974992/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=33763744&amp;postID=115722507482974992' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/33763744/posts/default/115722507482974992'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/33763744/posts/default/115722507482974992'/><link rel='alternate' type='text/html' href='http://reedobrien.blogspot.com/2006/09/first-post.html' title='First Post'/><author><name>reedobrien</name><uri>http://www.blogger.com/profile/15835081896608317143</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry></feed>
