Jul 22

pop2smtp: POP3 (“recojetodo”) a SMTP amb múltiples destins

Reading time: 2 – 3 minutes

Alguns ISPs ens permeten tenir una compte que reculli tot el correu enviat a un domini, això per exemple es pot usar com a mail-backup del nostre domini. Doncs bé a través de fetchmail és molt senzill re-injectar el correu enmagatzemat a una compte POP3 a un servidor SMTP contra un usuari. El més complicat, és si el correu que hi ha a la compte POP3 pot anar a més d’un destí, com el que deia fa un moment en comptes POP3 tipus ‘recojetodo’ o cul de sac com diuen alguns.

Doncs bé, per això he fet un petit script en python que a partir d’un fitxer BSMTP modifica la companda RCPT TO en funció de la informació de l’etiqueta Envelope to que conté una llista de les comptes d’email destí a qui va dirigit el correu. Així doncs, bàsicament la tasca consisteix en buscar quines comptes d’email apareixen a l’etiqueta comentada i després borrem la comanda RCPT TO i creem tantes comandes d’aquest tipus com faci falta en el seu lloc per enviar copies del correu que volem enviar als seus destins. Aquest nou fitxer BSMTP modificat l’injectem al nostre MTA. Aquest MTA serà l’encarregat de processar aquest correus i entregar-los a les comptes destí.

En el meu cas he decidit fer un petit shell script que s’executa des del crontab cada 10min. Aquest script, Crida a fetchmail per obtenir el fitxer BSMTP amb el correu que hi havia a la compte POP3, després crida l’script de python per modificar el fitxer BSMTP d’entrada tal com he comentat i crea un nou fitxer BSMTP de sortida. Finalment aquest fitxer s’injecta via SMTP cridant un petit script que gràcies al NetCat envia per SMTP el contingut del fitxer BSMTP de sortida.

L’script amb l’estructura de directoris empaquetat en un fitxer: pop2smtp_r1.tar.gz.

Segur que hi ha formes més elegants de resoldre el problema, però la veritat no les he sabut trobar.

Jun 03

Python: Reiniciem el router si no hi ha internet

Reading time: 1 – 2 minutes

Malgrat fa uns dies vaig canviar el meu vell Zyxel per un Cisco 837 a casa, la línia ADSL es continua penjant per motius desconneguts. Ja que quan les dades no circulen ni amunt ni aball les interficies ATM estan aixecades i tot sembla funcionar correctament. Així doncs, no m’ha tocat altre remei que fer-me un petit script amb Python a través del qual cada 5min comprovo si tornen els pings contra un dels servidors de OpenDNS. Si això no és així llavors es connecta contra el router Cisco i el reinicia. Ja que he fet proves baixant i pujant la interficie ATM i no hi ha manera. No se m’ha acudit cap millor idea que llençar un reload.

L’script guarda un fitxer de log a /var/log/online.log i usa el modul pexpect de Python. La resta de coses que usa són moduls que van instal·lats per defecte.

Si a algú li pot fer falta l’script el podeu descarregar: router.py.

Apr 27

Python trick: error Address already in use

Reading time: 1 – 2 minutes

Quan treballem amb sockets en python sovint al publicar un port si matem el procés que publicava el port encara que sigui de forma correcte ens trobem que al llençar-lo de nou, o sigui, a l’intentar publicar altre cop el procés aquest dona error un error que diu algo així com Address already in use. O sigui, que el sistema operatiu es pensa que el port encara esta sent publicat pel procés que ja em matat. Si fem un netstat veiem que el port no hi és, però encanvi fins al cap d’una estoneta (alguns segons o minuts) no hi ha manera de poder usar de nou aquest port.

Doncs bé, un petit truquillo perquè això no passi i el poguem usar a l’instant és fer això després de crear l’objecte de la classe socket:

# creació de l'objecte
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# afegim noves propietats a l'objecte
server.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)

Jan 02

cleanup-maildir – netejant el maildir

Reading time: 2 – 2 minutes

Avui he trobat aquest article Cleanup Maildir folders (archive/delete old mails) | MDLog:/sysadmin i no he dubtat ni un segon en baixar-me l’script: cleanup-maildir (local) programat en python. De fet, el seu nom ja diu molt del que fa. Bàsicament jo l’uso per netejar el directori Junk. És a dir, allà on rebo les alertes de correus considerats spam, virus, phishing o d’altres malwares. És a dir, he posat l’script al cron i li he dit que el contingut de la carpeta Junk del maildir que tingui més de 15 dies es vagi eliminant. Així no m’he de preocupar d’anar borrant de forma periódica tot el correu mailiciós que ja mai miraré perquè ningú m’ha dit allò tan famós de: “T’he enviat un correu, no ho has vist?” i llavors comences a buscar per la carpeta on hi ha tota la brossa a veure si el troves. Doncs bé, ara només hi haurà 15 dies de brossa.

Realment és un script molt xorra però que el trobo molt útil, ja que té força opcions com per exemple no borrar els correus marcats com a llegits, o com a importants, o crear automàticament subcarpetes on guardar els correus que tenen una antiguitat determinada. Segurament encara em deixo alguna funció però jo diria que la idea queda més que clara.

Oct 11

python: Abyss Webserver start and stop host from CLI

Reading time: 1 – 2 minutes

Petit script en python per iniciar/parar el Abyss Webserver des de la línia de comandes. Només hem de posar la URL d’on es troba la web de la consola de l’Abyss i l’ususari i el password per entrar-hi. Com que esta fet ràpid i corrents, no es suporta el pas de paràmetres per indicar si s’ha d’engegar i/o parar el servei en cada moment. Així que si algú s’anima a afegir-hi les 4 línies de codi que hi falten que me les digui, que jo encara no domino prou el python com per fer-ho en 1s i avui ja estic cansat.

import urllib2

theurl = 'http://127.0.0.1:9999' username = 'theuser' password = 'thepass'
passman = urllib2.HTTPPasswordMgrWithDefaultRealm() passman.add_password(None, theurl, username, password) authhandler = urllib2.HTTPBasicAuthHandler(passman) opener = urllib2.build_opener(authhandler)
data_start = "%2Fhosts%2Fhost%400%2Fstart=Start" data_stop = "%2Fhosts%2Fhost%400%2Fstop=Stop"
data = data_start
request = urllib2.Request(theurl,data) response = opener.open(request)
print response.readlines()

Oct 11

python: Autenticació HTTP de tipus basic-scheme

Reading time: 1 – 2 minutes

Com accedir a un serividor HTTP amb les pàgines protegides amb usuari i password del tipus Basic Authentication Scheme.

import urllib2

theurl = 'http://host:port' username = 'theuser' password = 'thepass'
# this creates a password manager passman = urllib2.HTTPPasswordMgrWithDefaultRealm() # because we have put None at the start it will always use this # username/password combination passman.add_password(None, theurl, username, password) # create the AuthHandler authhandler = urllib2.HTTPBasicAuthHandler(passman) # Return an OpenerDirector instance, which chains the handlers in the # order given Return an OpenerDirector instance, which chains the # handlers in the order given opener = urllib2.build_opener(authhandler) # Install an OpenerDirector instance as the default global opener urllib2.install_opener(opener) # Open the URL url, which can be either a string or a Request object. pagehandle = urllib2.urlopen(theurl) lines = pagehandle.readlines()
for line in lines: print line

L’autentació que usa l’Abyss Webserver per defecte és la del tipus explicada en aquest exemple.

Oct 06

python: Generar passwords d’usuaris per l’Abyss Webserver

Reading time: < 1 minute

L’Abyss Webserver guarda en un fitxer de configuració en format XML els usuaris i passwords. Doncs bé el format en que estan enmagatzemats els passwords en el fitxer XML és:

usercode = nom_usuari + ":" + plaintext_password
encoded_password = md5(base64(usercode))

Doncs bé aquí ve el petit trick de com fer això amb python:

#!/usr/bin/env python
import md5
import base64
import re

def genera_pass_abyss(usercode): b64usercode = base64.encodestring(usercode) b64usercode = re.sub('\n','',b64usercode) hash = md5.new(b64usercode) return hash.hexdigest()
user = 'usuari1' passw = 'password1' usercode = user + ":" + passw print usercode print genera_pass_abyss(usercode)

Sep 26

pyGTK, Glade i SPE (Stani’s Python Editor)

Reading time: 2 – 4 minutes

SPE és l’editor que he començat a usar avui per programar en Python, concretament me l’he instal·lat per la facilitat d’acompletar les comandes especialment per accedir al binding de GKT+ (pyGTK). No és que m’hagi donat per programar en Python però porto un parell de dies liat amb el tema, ahir amb els webservices amb SOAP via SOAPpy i avui amb el pyGTK per tal de modificar una aplicació de compte enrera, concretament Countdown timer.

countdowntimer.png

Bàsicament el primer que he fet és modificar l’aparença de l’aplicació amb el Glade. Aquesta eina ens permet crear i editar GUI de forma senzillíssima. Arrossegant components i assignant mètodes que capturin les senyals dels components de l’aplicació, modificant els atributs dels components, etc. Realment sense tenir-ne ni idea el Glade ens crea un fitxer XML amb l’aparença d’una aplicació realment atractiva i còmode d’usar per l’usuari final.

glade.png

Tornant a l’SPE, doncs no esta malament és força còmode d’usar i té cosetes interessants, com ara la shell de python i un debuger. Però hi he trobat diversos inconvenients que em tenen una mica mosca. L’aplicació es penja moltíssim si usem el seu launcher per provar l’aplicatiu que estem desenvolupament. A més el debuger també es penja només invocar-lo. Suposo que deu ser algún problema de la instal·lació en gentoo.

spe.png

Però com a IDE també li trobo algunes mancances. Suposo que estic massa ben acostumat amb el Zend Studio. El problema esta en que jo voldria disposar d’ajuda en línia quan les opcions d’autocompletat de comandes es llencen així podria saber quina és la funció de GTK o Python que m’interessa en cada moment. Però no només no fa això sinó que la llista de funcions que dona per autocompletar sovint és reduida i no pas la llista completa de funcions suportades per l’objecte.

De fet, he trobat algún altre IDE per Python força interessant, com ara Wing IDE el problema és que és de pagament. Obviament sempre que puc uso vim. Però no vull acabar sent ni un expert de Python, ni de GTK, ni de pyGTK, ni res de tot això només sortir del pas el més ràpid possible amb aquesta necessitat i la veritat no trobo cap IDE que m’ajudi el suficient.