Sunday, July 08, 2012

Windows Shares vs. FTP vs. FTPS vs. SFTP

Conducted this little test between a Windows 7 machine and Windows XP machine on a 100 Mbit switch. 

Used FileZilla server for FTP and FTPS server, FileZilla as FTP and FTPS client, Cygwin OpenSSH as SFTP server and WinSCP as SFTP client.

Was surprised to see how much overhead there was on FTPS, but it could also be something specific to FileZilla.

Windows sharesFTP FTPSSFTP
2700 files, 200Mb4,17 Mb/sec
48 secs
4,76 Mb/sec
42 secs
0,61 Mb/sec
326 secs
3,03 Mb/sec
66 secs
1 file, 550Mb9,82 Mb/sec
56 secs
11,22 Mb/sec
49 secs
11,00 Mb/sec
50 secs
6,25 Mb/sec
88 secs

Friday, July 06, 2012

Finding all machines a user owns in Active Directory

Here's a quick and dirty way to find all machines a user owns in Active Directory. Performance is not good though, as the objects are processed client side. I was not able to find any way of doing server side queries dealing with the ntSecurityDescriptor field. Please let me know if you find a way!

Adjust the DN strings as needed.

using System;
using System.DirectoryServices;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            DateTime startTime = DateTime.Now;

            DirectoryEntry d = new DirectoryEntry("LDAP://ou=UserAccounts,dc=contoso,dc=com");
            DirectorySearcher s = new DirectorySearcher(d, "(&(objectClass=user)(cn=John Smith))",
                new string[] { "cn", "objectsid" });

            string sid = BitConverter.ToString(
                    (byte[])s.FindOne().Properties["objectsid"][0])
                .Replace("-", "");

            int count = 0;
            d = new DirectoryEntry("LDAP://ou=Machines,dc=contoso,dc=com");
            s = new DirectorySearcher(d, "(&(objectCategory=computer)(objectClass=computer)(cn=*))",
                new string[] { "cn", "ntSecurityDescriptor" });
            s.PageSize = 500;
            s.SecurityMasks = SecurityMasks.Owner;
            foreach (SearchResult r in s.FindAll())
            {
                count++;
                string cn = (string)r.Properties["cn"][0];
                string sd = BitConverter.ToString((byte[])r.Properties["ntsecuritydescriptor"][0]).Replace("-", "");

                if (sd.Contains(sid))
                    Console.WriteLine(cn);
            }

            Console.WriteLine();
            Console.WriteLine("Checked " + count + " objects");
            Console.WriteLine("Query finished in " + (DateTime.Now - startTime));
        }
    }
}

Tuesday, June 26, 2012

Compiling Bootstrap LESS on Windows

The current version of Bootstrap can neither be compiled on WinLess nor lessc.exe as of writing. I found that these days the easiest is actually to run the Windows version of Node.js. Standalone single .exe versions of Node.js are available. Go download the less.js source and you can make yourself a "lessjs.cmd" with something like the following:
d:\utils\node.exe d:\utils\lesscss\bin\lessc %1

Monday, April 30, 2012

Django as a micro framework, including models

The following can be used as a base when you want to avoid the normal structure Django imposes on your project, and you just want everything in a single file.

It is based on similar attempts by Ivan Sagalaev and Fahrzin Hemmati (especially this gist), and a post on stack overflow.

A thing that I consider an improvement over Fahrzin Hemmati's version is that models don't need the explicit app_label and __module__.

#
# Django as a microframework skeleton, by Allan Boll, 1 May 2012
# Based on http://softwaremaniacs.org/blog/2011/01/07/django-micro-framework/en/
# and https://gist.github.com/2219751
#

#
# Settings
#
appname = 'app'
from django.conf import settings
if not settings.configured:
    settings.configure(
        SITE_ID=1,
        TEMPLATE_DIRS=['.'],
        DATABASES = {
            'default':{
                'ENGINE':'django.db.backends.sqlite3',
                'NAME': 'db',
            }
        },
        DEBUG=True,
        TEMPLATE_DEBUG=True,
        ROOT_URLCONF = __name__,
        STATIC_URL='/static/',
        STATICFILES_DIRS=['./static/'],
        INSTALLED_APPS=(
            'django.contrib.auth',
            'django.contrib.contenttypes',
            'django.contrib.sessions',
            'django.contrib.messages',
            'django.contrib.staticfiles',
            'django.contrib.admin', 
        )
    )

#
# Models
#
from django.db import models

# Workaround to allow models in current file
import sys
sys.modules[appname+'.'] = sys.modules[__name__]
old_module_name = sys.modules[__name__].__name__
sys.modules[__name__].__name__ = appname+'.'

class SomeModel(models.Model):
    field_name = models.CharField(max_length=10)

# Continuation of workaround to allow models in current file
sys.modules[__name__].__name__ = old_module_name


#
# Views
#
from django.shortcuts import render

def index(request):
    out = []
    for obj in SomeModel.objects.all():
        out.append(obj.field_name)
    return render(request, 'index.html', {'s': ', '.join(out)})


#
# URL configuration
#
from django.conf.urls.defaults import patterns, url, include

urlpatterns = patterns('',
    (r'^$', index),
)


#
# Admin site
#
from django.contrib import admin
from django.contrib.auth.admin import UserAdmin, GroupAdmin
from django.contrib.auth.models import User, Group

admin.site = admin.AdminSite()
admin.site.register(User, UserAdmin)
admin.site.register(Group, GroupAdmin)
admin.site.register(SomeModel)

urlpatterns = patterns('',
    url(r'^admin/', include(admin.site.urls))
) + urlpatterns


#
# Running
#
if __name__=='__main__':
    # Monkey patch get_app to allow models in current file
    get_app_orig = models.get_app
    def get_app(app_label,*a, **kw):
        if app_label==appname:
            return sys.modules[__name__]
        return get_app_orig(app_label, *a, **kw)
    models.get_app = get_app

    # Add models in current file to global list of apps
    models.loading.cache.app_store[type(appname+'.models',(),{'__file__':__file__})] = appname

    from django.core import management
    management.execute_from_command_line()

Friday, February 10, 2012

Sublime Text default to empty file

I recently began using the editor Sublime Text. Previously I was using Notepad++ which is also a fine editor, but not as "futuristic" as Sublime Text. I had gotten used to Notepad++'s behaviour of defaulting to an empty file when all tabs are closed, and found that this behaviour was easy to achieve in Sublime Text as well, thanks to its amazing API. To get the behaviour, drop the following Python source into something like Data/Packages/User/default_to_empty_file.py.


import sublime, sublime_plugin

class DefaultToEmptyFile(sublime_plugin.EventListener):
def on_close(self, view):
for window in sublime.windows():
if window == None:
continue

if len(window.views()) <= 1:
window.new_file()

def on_load(self, view):
window = view.window()
if window == None:
return

views = window.views()
if len(views) == 2:
for v in views:
if v != view and v.file_name() == None and v.size() == 0:
window.focus_view(v)
window.run_command('close_file')

Friday, December 30, 2011

Raw sockets with BPF in Python

Update 2021: Note that this was written in 2011. Nowadays I'd not recommend doing it this way, but instead using BCC to write your filters in C, from within Python. The following example shows the use of raw sockets where filtering is applied using BPF. It has only been tested on Linux. The filter data structure is built up to form a machine language-like set of instructions that decide whether the packet should be passed to the raw socket or not. The filter is applied to the socket using SO_ATTACH_FILTER. This specific example filters packets to only allow packets destined a DHCP server (UDP port 67).
from binascii import hexlify
from ctypes import create_string_buffer, addressof
from socket import socket, AF_PACKET, SOCK_RAW, SOL_SOCKET
from struct import pack, unpack


# A subset of Berkeley Packet Filter constants and macros, as defined in
# linux/filter.h.

# Instruction classes
BPF_LD = 0x00
BPF_JMP = 0x05
BPF_RET = 0x06

# ld/ldx fields
BPF_H = 0x08
BPF_B = 0x10
BPF_ABS = 0x20

# alu/jmp fields
BPF_JEQ = 0x10
BPF_K = 0x00

def bpf_jump(code, k, jt, jf):
    return pack('HBBI', code, jt, jf, k)

def bpf_stmt(code, k):
    return bpf_jump(code, k, 0, 0)


# Ordering of the filters is backwards of what would be intuitive for 
# performance reasons: the check that is most likely to fail is first.
filters_list = [
    # Must have dst port 67. Load (BPF_LD) a half word value (BPF_H) in 
    # ethernet frame at absolute byte offset 36 (BPF_ABS). If value is equal to
    # 67 then do not jump, else jump 5 statements.
    bpf_stmt(BPF_LD | BPF_H | BPF_ABS, 36),
    bpf_jump(BPF_JMP | BPF_JEQ | BPF_K, 67, 0, 5),

    # Must be UDP (check protocol field at byte offset 23)
    bpf_stmt(BPF_LD | BPF_B | BPF_ABS, 23), 
    bpf_jump(BPF_JMP | BPF_JEQ | BPF_K, 0x11, 0, 3),

    # Must be IPv4 (check ethertype field at byte offset 12)
    bpf_stmt(BPF_LD | BPF_H | BPF_ABS, 12), 
    bpf_jump(BPF_JMP | BPF_JEQ | BPF_K, 0x0800, 0, 1),

    bpf_stmt(BPF_RET | BPF_K, 0x0fffffff), # pass
    bpf_stmt(BPF_RET | BPF_K, 0), # reject
]

# Create filters struct and fprog struct to be used by SO_ATTACH_FILTER, as
# defined in linux/filter.h.
filters = ''.join(filters_list)
b = create_string_buffer(filters)
mem_addr_of_filters = addressof(b)
fprog = pack('HL', len(filters_list), mem_addr_of_filters)

# As defined in asm/socket.h
SO_ATTACH_FILTER = 26

# Create listening socket with filters
s = socket(AF_PACKET, SOCK_RAW, 0x0800)
s.setsockopt(SOL_SOCKET, SO_ATTACH_FILTER, fprog)
s.bind(('eth0', 0x0800))

while True:
    data, addr = s.recvfrom(65565)
    print 'got data from', addr, ':', hexlify(data)

Thursday, December 08, 2011

Simple heap implementation in C#

I recently needed a simple priority queue in C# and was surprised to find that there is neither anything called "priority queue" nor "min heap" or "max heap" in .NET (or at least I did not find it when I looked). Here is a textbook-like implementation I came up with:

class MinHeap<T> where T : IComparable
{
    private List<T> data = new List<T>();

    public void Insert(T o)
    {
        data.Add(o);

        int i = data.Count - 1;
        while (i > 0)
        {
            int j = (i + 1) / 2 - 1;

            // Check if the invariant holds for the element in data[i]
            T v = data[j];
            if (v.CompareTo(data[i]) < 0 || v.CompareTo(data[i]) == 0)
            {
                break;
            }

            // Swap the elements
            T tmp = data[i];
            data[i] = data[j];
            data[j] = tmp;

            i = j;
        }
    }

    public T ExtractMin()
    {
        if (data.Count < 0)
        {
            throw new ArgumentOutOfRangeException();
        }

        T min = data[0];
        data[0] = data[data.Count - 1];
        data.RemoveAt(data.Count - 1);
        this.MinHeapify(0);
        return min;
    }

    public T Peek()
    {
        return data[0];
    }

    public int Count
    {
        get { return data.Count; }
    }

    private void MinHeapify(int i)
    {
        int smallest;
        int l = 2 * (i + 1) - 1;
        int r = 2 * (i + 1) - 1 + 1;

        if (l < data.Count && (data[l].CompareTo(data[i]) < 0))
        {
            smallest = l;
        }
        else
        {
            smallest = i;
        }

        if (r < data.Count && (data[r].CompareTo(data[smallest]) < 0))
        {
            smallest = r;
        }

        if (smallest != i)
        {
            T tmp = data[i];
            data[i] = data[smallest];
            data[smallest] = tmp;
            this.MinHeapify(smallest);
        }
    }
}