Category Archives: Programming

MM_XSLTransform Error

MM_XSLTransform error.
[RSS URL] is not a valid XML document.
 Non-static method DOMDocument::loadXML() should not be called statically,
assuming $this from incompatible context in file

I recently came across this error and took me a lot of searching to find out the right fix for it. Here is where you can find the fix.

http://groups.google.com/group/macromedia.dreamweaver.appdev/browse_thread/thread/832446ccb50569f3

, ,

Secure Firewall for OpenVPN

Creating a secure firewall is essential for any openvpn configuration.

First of all, I’d strongly recommend grabbing a copy of Linux Firewalls.
Its got a great section on iptables, with a look at all the commands available to you
as well as an example firewall configuration.

I have setup an openVPN which has a configuration where there are three different types of user.

1. Customers
2. Suppliers
3. Support

As far as the VPN knows, these are all the same thing -> a node on the network. It is in the firewall that I will put my rules to govern who can ‘see’ whom.

Customers are grouped into “Companies”. Every customer must be able to see every other customer
in their company.

Every supplier node must be able to see every customer that they have supplied a system to.

Every support agent must be able to see every customer.

All other connections should be blocked

Note of Caution
The *only* way to be able to have a chance of doing this kind of configuration is by knowing what each
nodes VPN ip address is, or what group of ip addresses it could be in.
That means that you have to use ccd in your sever settings

My Firewall
First, I make sure that ip forwarding is enabled on the server. You can check if it is enabled by typing

cat /proc/sys/net/ipv4/ip_forward

if it shows 0, it is disabled. 1 means enabled.

echo 1 > /proc/sys/net/ipv4/ip_forward

forces it to be enabled

Then, I run my firewall rules. First I want to ensure that the default behaviour for any packet is to be dropped

iptables --policy FORWARD DROP

I want to log anything that is passed between nodes:

iptables -A FORWARD -i tun0 -j LOG --log-level 6 --log-prefix 'Forward tun0 Log'

Then, for every pair of nodes that I want to see each other I run this command:

iptables -A FORWARD -i tun0 -s 10.2.2.5 -d 10.2.2.1 -j ACCEPT

That says allow packets to go from 10.2.2.5 to 10.2.2.1. Of course, for that to work, we
also need to allow packets to go the other way.

iptables -A FORWARD -i tun0 -s 10.2.2.1 -d 10.2.2.5 -j ACCEPT

Another Note Of Caution
In order for the above configuration to work, I push all routes to all nodes in my server.conf file
route 10.0.0.0 255.0.0.0
That means that the firewall is the ‘all powerful’ being that can control and change who can see what
at any point in time, without having to touch the vpn configuration.

Scripting the firewall
I’ve written a little python script to ensure that I don’t make errors when creating my firewall
every time a supplier/customer/support member is added.

Config File

The config file for the script is made up of 3 parts.
1. IP addresses. These map to the ones that you have assigned to each node in the ccd directory
of your server.conf setup.
2. PermissionGroups. These are groups of the ipaddresses useful for setting permissions
3. Permissions. These are the permissions that are setup for the firewall rules to fire against.

#config.py
#IP_ADDRESSES - create an ip address for each node in the vpn.

IP_OPEN_VPN_SERVER = "10.8.0.1" #not really needed, for reference only

#CompanyA
COMPANYA_CUSTOMER1 = "10.2.1.1"
COMPANYA_CUSTOMER2 = "10.2.1.5"
COMPANYA_CUSTOMER3 = "10.2.1.9"

GRP_COMPANY_A = [COMPANYA_CUSTOMER1, COMPANYA_CUSTOMER2, COMPANYA_CUSTOMER3]

#CompanyB
COMPANYB_CUSTOMER1 = "10.2.2.1"
COMPANYB_CUSTOMER2 = "10.2.2.5"
COMPANYB_CUSTOMER3 = "10.2.2.9"

GRP_COMPANY_B = [COMPANYB_CUSTOMER1, COMPANYB_CUSTOMER2, COMPANYB_CUSTOMER3]

#SUPPLIERS
SUPPLIER1 = "10.3.1.1"
SUPPLIER2 = "10.3.1.5"

#SUPPORT PEOPLE
SUPPORT1 = "10.1.1.1"
SUPPORT2 = "10.1.1.5"
SUPPORT3= "10.1.1.9"

GRP_SUPPORT = [SUPPORT1, SUPPORT2, SUPPORT3]

#PERMISSION GROUPS

#Who should support be able to see
PERM_SUPPORT = [COMPANYA_CUSTOMER1, COMPANYA_CUSTOMER2, COMPANYA_CUSTOMER3,
COMPANYB_CUSTOMER1, COMPANYB_CUSTOMER2, COMPANYB_CUSTOMER3]

PERM_COMPANY_A = [COMPANYA_CUSTOMER1, COMPANYA_CUSTOMER2, COMPANYA_CUSTOMER3]

PERM_COMPANY_B = [COMPANYB_CUSTOMER1, COMPANYB_CUSTOMER2, COMPANYB_CUSTOMER3]

PERM_SUPPLIER1 = PERM_COMPANY_A

PERM_SUPPLIER2 = PERM_COMPANY_B

#Permissions is a dictionary of 'this ip should be able to communicate with': [these ips]
#as a result, a path is created between each key and every ip in the values
PERMISSION_GROUPS = {GRP_SUPPORT: PERM_SUPPORT,
GRP_COMPANY_B:PERM_COMPANY_B,
GRP_COMPANY_A:PERM_COMPANY_A,
[SUPPLIER1]: PERM_SUPPLIER1,
[SUPPLIER2]: PERM_SUPPLIER2}

PERMISSIONS = {}
for group, permissions in PERMISSION_GROUPS.iteritems():
for ipaddress in group:
PERMISSIONS[ipaddress] = permissions

Firewall Script
Now here’s the firewall script that will turn your config file into a living, breathing firewall.

#autoConfigure.py
""This module deals with the ip rules for the customers, suppliers and support over the VPN!"""

from config import PERMISSIONS
import os

class SomethingWentWrongException(Exception):pass

def runFireWallRule(rule):
ans = os.system(rule)
if ans==0:
return True
else:
raise SomethingWentWrongException

def resetFireWall():
runFireWallRule("iptables -F")

def loadFireWall(logging=True):
#allow port forwarding
runFireWallRule("echo 1 > /proc/sys/net/ipv4/ip_forward")
runFireWallRule("iptables --policy FORWARD DROP")
if logging:
runFireWallRule("iptables -A FORWARD -i tun0 -j LOG --log-level 6 --log-prefix 'Forward tun0 Log'")
for rootIP, destinations in PERMISSIONS.items():
"""creates routed from the rootIP to destinationIP and back again"""
for destination in destinations:
if rootIP!=destination:
runFireWallRule("iptables -A FORWARD -i tun0 -s %s -d %s -j ACCEPT"%(rootIP, destination))
runFireWallRule("iptables -A FORWARD -i tun0 -s %s -d %s -j ACCEPT"%(destination, rootIP))

if __name__=='__main__':
resetFireWall()
loadFireWall()

Try running the autoconfigure.py file, as root, and see what the output is of iptables -L

wxpython Segmentation Fault

In some of my wx python apps, I have come across this error.
It usually appears like this on the command line

Segmentation Fault (core dumped)

The most common reason for me getting this error, has been when a non-main thread tries to directly manipulate something in wx. Be it to Hide() a window, or ShowModal() a dialog.

The way to get round this (and actually, the way to use wx correctly, so I’m told), is to use the event handlers to pass messages back from your sub-processes to the wx event loop.

To create your own event class you can do this:

#First we'll define a new event type
wxEVT_THREAD_COM = wx.NewEventType()

#Now you can define your own event
class ThreadEvent(wx.PyEvent):
def __init__(self, id, data=None):
wx.PyEvent.__init__(self)
self.SetEventType(wxEVT_THREAD_COM)
self.data = data
self.id = id

Once you’ve done that, you can create an event handler in the frame you want to pass the event to.


#now we'll create a handler in our main frame class
class MainFrame(wx.Frame):
def __init__(self):
wx.Frame.__init__(....)
self.Connect(-1, -1, wxEVT_THREAD_COM, self.OnThreadCommunicationEvent)

def OnThreadCommunicationEvent(self, event):
#handle the event here
if event.id==CLOSE:
self.Close()
elif event.id==HIDE:
self.Hide()
event.Skip()

To pass launch an event, you just need to get the event handler for the wx object, and then add the event!

#assuming MAIN_FRAME is a reference to the MAIN_FRAME in a foreign thread
myThreadEvent = ThreadEvent(CLOSE)
MAIN_FRAME.GetEventHandler().AddPendingEvent(myThreadEvent)

Part 3: Setting up the schedule

Part3: Setting up the schedule

So you’ve got the python screen capturer and emailer sorted. Now all we need to do is combine the two and set up a process to perform on a regular basis.

1. ScreenMailer

First, we’ll combine the two. When this module is run, it should grab a screen image and send it as is to an email address.

You’ll need to edit a few things. First of all, change the imageName to be in a folder that you don’t mind storing some images.
In my example, I’ve stored it in /tmp (on linux).

The other thing you’ll want to change is your user details.
a) change myEmail to be your email address
b) change userdetails.destination to be the destination email address (this can be the same thing!)
c) change userdetails.username and username.password to have your correct values.
d) if you are not using gmail, find the smtp server address and enter it in serverAddr

#screenMailer.py
import time
import emailer
import screen

def grabScreenAndSend():

imageName = ‘/tmp/images/image%s.gif’%int(time.time())

screen.grabScreen(imageName)

myEmail = ‘xyz@gmail.com’
serverAddr = ‘smtp.gmail.com’
destination = userdetails.destination
timeNow = time.strftime(“%H:%M”, time.localtime())
dayNow = time.strftime(“%a, %d %b %Y”, time.localtime())

emailer.sendEmail(destination, myEmail, ‘My Screen %s’%dayNow,
‘2 Minute Interval Screen Shot, taken at %s. this is just for the filter’%timeNow, serverAddr,
userdetails.username, userdetails.password, [imageName])

if __name__==’__main__’:
grabScreenAndSend()

2. Setting up the scheduler:
a) On linux type crontab -e to edit
add this line

*/2 * * * * python2.4 address_to_your_screen_mailer/screenMailer.py

That will launch the screenMailer every 2 minutes of every day. If you just want the hourly report rather than every two minutes, change the screenMailer.py file so that it does not send the picture. You’ll still need it to run in order to get the hourly report to work

b) on windows use the scheduler, I’ll find out how to do this and edit later on!

3. The hourly summary.

In order to send an hourly summary, we need to create our hourlyScreenSummary.py file.
It takes all of the images found in the folder given and creates a collage and then sends that.
You’ll need to make some more changes for your configuration here.
a) change the OUT_FILE to an appropriate location. this file will get deleted after each run.
b) change the FOLDER to be the same as you set before, where all of the 2 minute pictures were saved
c) change myEmail to be your email address
d) change userdetails.destination to be the destination email address (this can be the same thing!)
e) change userdetails.username and username.password to have your correct values.
f) if you are not using gmail, find the smtp server address and enter it in serverAddr

#hourlyScreenSummary.py
import screenMailer
import emailer
import time
import os
import extras
from config import launchCommand

#combines the whole contents of a specific folder and sends it as one image

OUT_FILE = ‘/tmp/montage.gif’
FOLDER = ‘/tmp/images’

def createMontage(folderaddr):
if platform.system()==’Windows’ or platform.system()==’Microsoft’:
createPILMontage(folderaddr)
else:
createLinuxMontage(folderaddr)

def createLinuxMontage(folderaddr):
files=[]
for filename in os.listdir(folderaddr):
files.append(‘%s/%s’%(folderaddr, filename))

filestring = ‘ ‘.join(files)

launchCommand(‘montage %s -geometry +2-2 %s’%(filestring, OUT_FILE))

def createPILMontage(folderaddr):
import extras
files=[]
for filename in os.listdir(folderaddr):
files.append(‘%s/%s’%(folderaddr, filename))
if len(files):
nocols = 5
norows = int(len(files)/5)+1
newFile = extras.make_contact_sheet(files,(ncols,nrows),(160,100),
(0,0,0,0),2)
newFile.save(OUT_FILE)
def removeImageFiles(folderaddr):
files = []
for filename in os.listdir(folderaddr):
os.remove(‘%s/%s’%(folderaddr, filename))

def createAndSendHourlyScreenSummary():
“””create and send an hourly screen summary”””
createMontage(FOLDER)
timeNow = time.strftime(“%H:%M”, time.localtime())
dayNow = time.strftime(“%a, %d %b %Y”, time.localtime())

myEmail = ‘xyz@gmail.com’
destination = userdetails.destination
serverAddr = ‘smtp.gmail.com’
emailer.sendEmail(destination, myEmail, ‘My Hourly Screen %s’%dayNow,
‘Hourly Screen Summary, taken at %s this is just for the filter’%timeNow, serverAddr,
userdetails.username, userdetails.password, [OUT_FILE])
#now remove the contents of that file
removeImageFiles(FOLDER)

if __name__==’__main__’:
createAndSendHourlyScreenSummary()

4. Add to crontab again
You’ll now need to add this to crontab aswell. Add the following line after typing crontab -e at the command line:

1 * * * * python2.4 (path to hourlyScreenSummary)/hourlyScreenSummary.py

This will send the hourly montage to the address that you have hard coded every hour.

5. And finally
There is one more module that you will need. I found this from http://www.mirrorservice.org/sites/download.sourceforge.net/pub/sourceforge/v/vi/vidag/montager and have editted it slightly
This module is for the windows version only and is used to create a sheet of screen shots.

#extras.py
import Image

def make_contact_sheet(fnames,(ncols,nrows),(photow,photoh),
(marl,mart,marr,marb),
padding):
“””\
Make a contact sheet from a group of filenames:

fnames A list of names of the image files

ncols Number of columns in the contact sheet
nrows Number of rows in the contact sheet
photow The width of the photo thumbs in pixels
photoh The height of the photo thumbs in pixels

marl The left margin in pixels
mart The top margin in pixels
marr The right margin in pixels
marl The left margin in pixels

padding The padding between images in pixels

returns a PIL image object.
“””

# Read in all images and resize appropriately
imgs = [Image.open(fn).resize((photow,photoh)) for fn in fnames]

# Calculate the size of the output image, based on the
# photo thumb sizes, margins, and padding
marw = marl+marr
marh = mart+ marb

padw = (ncols-1)*padding
padh = (nrows-1)*padding
isize = (ncols*photow+marw+padw,nrows*photoh+marh+padh)

# Create the new image. The background doesn’t have to be white
white = (255,255,255)
inew = Image.new(‘RGB’,isize,white)

# Insert each thumb:
for irow in range(nrows):
for icol in range(ncols):
left = marl + icol*(photow+padding)
right = left + photow
upper = mart + irow*(photoh+padding)
lower = upper + photoh
bbox = (left,upper,right,lower)
try:
img = imgs.pop(0)
except:
break
inew.paste(img,bbox)
return inew

6. Finished

You are finished! You should be able to produce and send images of your desktop to be viewed in your inbox!

Part 1: Python Screen Capture
Part 2: Python Emailer

Part 2: Python Emailer

Part 2: Python Emailer

If you want to send emails using python’s smtplib, this is a good example.
The method sendMail takes 8 arguments and is able to send attached emails to an address.
Currently, this is only tested using my gmail account as the sender, but it should work elsewhere.

#emailer.py
import os.path
import sys, smtplib, MimeWriter, base64, StringIO
import smtplib
import mimetypes
from email.Encoders import encode_base64
from email.MIMEAudio import MIMEAudio
from email.MIMEBase import MIMEBase
from email.MIMEImage import MIMEImage
from email.MIMEMultipart import MIMEMultipart
from email.MIMEText import MIMEText

def getAttachment(path, filename):
“””Returns the attachment as a MIME formatted object”””
ctype, encoding = mimetypes.guess_type(path)
if ctype is None or encoding is not None:
ctype = ‘application/octet-stream’
maintype, subtype = ctype.split(‘/’, 1)
fp = open(path, ‘rb’)
if maintype == ‘text’:
attach = MIMEText(fp.read(),_subtype=subtype)
elif maintype == ‘message’:
attach = email.message_from_file(fp)
elif maintype == ‘image’:
attach = MIMEImage(fp.read(),_subtype=subtype)
elif maintype == ‘audio’:
attach = MIMEAudio(fp.read(),_subtype=subtype)
else:
print maintype, subtype
attach = MIMEBase(maintype, subtype)
attach.set_payload(fp.read())
encode_base64(attach)
fp.close
attach.add_header(‘Content-Disposition’, ‘attachment’,
filename=filename)
return attach

def getTotalMessage(toAddr, fromAddr, subject, msg, attachmentFileNames):
“””given a to address, from address, subject, msg and any attachments, returns
a message ready to be sent”””
mymsg = MIMEMultipart()
mymsg[‘From’] = fromAddr
mymsg[‘To’] = toAddr
mymsg[‘Subject’] = subject
mymsg.attach(MIMEText(msg))
for path in attachmentFileNames:
filename = path.split(‘/’)[-1]
print ‘getAttachment’, path, filename
attach = getAttachment(path, filename)
mymsg.attach(attach)
return mymsg.as_string()

def sendEmail(toAddr, fromAddr, subject, msg, serverAddr,
username, password, attachmentFileNames=[]):
“””This is the function to run when sending an email: Designed for gmail,
may work elsewhere”””
msg = getTotalMessage(toAddr, fromAddr, subject, msg, attachmentFileNames)

server = smtplib.SMTP(serverAddr)
server.ehlo(”)
server.starttls()
server.ehlo(”)
server.login(username, password)
server.sendmail(fromAddr, toAddr, msg)
server.quit()

Part 1: Python Screen Capture
Part 3: Setting up the schedule

Linux Windows Usage Surveillance in Python

Lets say you want to keep track of a computers usage, for remote working. It should deliver hourly shots of computer usage to an email address that you’ll give it. It will also deliver screen shots every 2 minutes, but you can choose whether it does that or not!

Part 1: Python Screen Capture
Part 2: Python Emailer
Part 3: Setting up the schedule

Part 1: Python Screen Capture

Requirements:

  • Python2.4 or greater
  • Windows or Linux based OS
  • On Windows, you’ll need to get Python Image Library
  • On Linux, you’ll need to have mogrify, which comes as part of ImageMagick.

If you don’t have it use your package manager to get it.

sudo apt-get install imagemagick

The screen module:

#screen.py
import os
import platform
import shutil
from config import launchCommand

def printScreen(filename):
“””prints the screen and saves it as the filename given”””
if platform.system()==’Windows’ or platform.system()==’Microsoft’:
import ImageGrab
img = ImageGrab.grab()
img.save(filename)
else:
launchCommand(‘/usr/bin/xwd -display :0 -root -out %s’%filename)

def convertImage(filename, width=160, height=100):
“””Converts the image found in filename to one of the dimensions given. returns a gif filename”””
if platform.system()==’Windows’ or platform.system()==’Microsoft’:
import Image
im1 = Image.open(filename)
im2 = im1.resize((width, height), Image.NEAREST)
im2.save(‘%s.gif’%filename)
else:
#320×200
launchCommand(‘/usr/bin/mogrify -format gif -resize %sx%s %s’%(width, height, filename))
return ‘%s.gif’%filename

def removeImage(filename):
“””removes the imagename given”””
os.remove(filename)

def copyFile(source,destination):
“””copys a file from source to destination”””
shutil.copyfile(source, destination)

def grabScreen(filename, width=160, height=100):
“””given a filename, width and height, grabs a screen shot of the current desktop,
scales it to the sizes passed in (default 160×100) and saves it to the filename given”””
tmpName = ‘tmp_image’
printScreen(tmpName)
imageName = convertImage(tmpName)
copyFile(imageName, filename)
removeImage(tmpName)
removeImage(imageName)