Friday, March 25, 2016

Segment tree implementation in Java

Inspired by Kartik Kukreja's implementation, but storing all data in a tree node class, rather than an array. I find it a lot easier to comprehend this way.
class SegmentTreeNode {
    public int aggregateValue;
    public SegmentTreeNode left;
    public SegmentTreeNode right;
    public int origLowIndex;
    public int origHighIndex;
}

class SegmentTreeTest {

    public static SegmentTreeNode buildSegmentTree(int[] a, int low, int high) {
        SegmentTreeNode n = new SegmentTreeNode();
        n.origLowIndex = low;
        n.origHighIndex = high;

        if(low == high) {
            n.aggregateValue = a[low];
            return n;
        }

        int mid = (high - low)/2 + low;

        n.left = buildSegmentTree(a, low, mid);
        n.right = buildSegmentTree(a, mid+1, high);

        // This segment tree is for summation. Could also be min, max, or any other associative func.
        n.aggregateValue = n.left.aggregateValue + n.right.aggregateValue;

        return n;
    }

    public static SegmentTreeNode getAggregateValue(SegmentTreeNode n, int low, int high) {
        if(n.origLowIndex == low && n.origHighIndex == high) {
            return n;
        }

        // The interval is fully contained within the left node
        if(low >= n.left.origLowIndex && high <=  n.left.origHighIndex) {
            return getAggregateValue(n.left, low, high);
        }

        // The interval is fully contained within the right node
        if(low >= n.right.origLowIndex && high <=  n.right.origHighIndex) {
            return getAggregateValue(n.right, low, high);
        }

        // Split into queries on the left subtree and the right subtree
        SegmentTreeNode leftResult = getAggregateValue(n.left, low, n.left.origHighIndex);
        SegmentTreeNode rightResult = getAggregateValue(n.right, n.right.origLowIndex, high);
        SegmentTreeNode result = new SegmentTreeNode();
        result.origLowIndex = low;
        result.origHighIndex  = high;

        // This segment tree is for summation. Could also be min, max, or any other associative func.
        result.aggregateValue = leftResult.aggregateValue + rightResult.aggregateValue;

        return result;
    }

    public static void update(SegmentTreeNode n, int index, int val) {
        if(n.origLowIndex == index && n.origHighIndex == index) {
            n.aggregateValue = val;
            return;
        }

        if(n.left.origLowIndex <= index && index <= n.left.origHighIndex) {
            update(n.left, index, val);
        } else {
            update(n.right, index, val);
        }

        // This segment tree is for summation. Could also be min, max, or any other associative func.
        n.aggregateValue = n.left.aggregateValue + n.right.aggregateValue;
    }

    public static void main(String[] args) {
        //                    0  1  2  3  4  5  6  7  8   9  10
        int[] a = new int[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 };
        SegmentTreeNode r = buildSegmentTree(a, 0, a.length-1);
        System.out.println(r.aggregateValue);

        System.out.println(getAggregateValue(r, 1, 3).aggregateValue);
        System.out.println(getAggregateValue(r, 4, 7).aggregateValue);

        update(r, 2, 10);
        System.out.println(r.aggregateValue);

        System.out.println(getAggregateValue(r, 4, 7).aggregateValue);
        System.out.println(getAggregateValue(r, 1, 3).aggregateValue);
    }
}

Friday, June 19, 2015

Windows scheduled task to auto logoff

Here's some PowerShell to remotely schedule a task to log out 2+ hours idle users:
function InstallAutoLogoff($computer)
{
    invoke-command -computer $computer `
    {
        schtasks.exe /delete /tn AutoLogOff /f 2>&1 | Out-Null

        set-content c:\windows\temp\AutoLogOffTask.xml `
        '<?xml version="1.0" encoding="UTF-16"?>
        <Task version="1.2" xmlns="http://schemas.microsoft.com/windows/2004/02/mit/task">
          <Triggers>
            <TimeTrigger>
              <Repetition>
                <Interval>PT30M</Interval>
              </Repetition>
              <StartBoundary>2015-01-01T00:00:00</StartBoundary>
            </TimeTrigger>
          </Triggers>
          <Actions Context="Author">
            <Exec>
              <Command>PowerShell.exe</Command>
              <Arguments>-Command $r1 = quser.exe; $idPos = $r1[0].IndexOf(''ID  ''); foreach($row in $r1) { $r2 = $row.Substring($idPos).Trim() -split ''  +''; if($r2[2].Contains('':'')) { $t = $r2[2].Replace('':'', ''.''); if($t.Contains(''+'') -or ($t -as [double] -ge 2)) { rwinsta.exe $r2[0] } } }</Arguments>
            </Exec>
          </Actions>
        </Task>'

        schtasks.exe /create /tn AutoLogOff /ru system /xml c:\windows\temp\AutoLogOffTask.xml
        del c:\windows\temp\AutoLogOffTask.xml
    }
}

InstallAutoLogoff 'myserver1'
InstallAutoLogoff 'myserver2'
InstallAutoLogoff 'myserver3'

Monday, March 23, 2015

VoCore OpenWRT as NAT access point

I recently bought a VoCore. It came pre-flashed with OpenWRT Chaos Calmer (as of 2015-03-16). OpenWRT was configured as a wireless access point, bridging with the ethernet port. Here is what I did to get it to a configuration where it acts as a NAT'ing wireless access point, similar to most consumer routers/access points:

SSH'ed to its default IP of 192.168.61.1.

Edited /etc/config/network:

...
#config interface 'lan'
config 'interface' 'wan'
      option macaddr 'b8:d8:12:60:00:01'
      option proto 'dhcp'

config interface 'lan'
  option force_link '1'
  option macaddr 'b8:d8:12:60:00:02'
  option proto 'static'
  option ipaddr '192.168.61.1'
  option netmask '255.255.255.0'
...

Edited /etc/config/wireless:

...
config wifi-iface
      option device   radio0
      option network  lan
      option mode     ap
      option ssid     gaffel8080
      option encryption psk2
      option key palle123
...

Edited /etc/config/dhcp:

...
#config odhcpd 'odhcpd'
# option maindhcp '0'
# option leasefile '/tmp/hosts/odhcpd'
# option leasetrigger '/usr/sbin/odhcpd-update'
...

To enable SSH from the ethernet port, I also edited /etc/config/firewall:

...
config rule
      option src wan
      option proto tcp
      option dst_port 22
      option target ACCEPT

This was all that was needed for the basic scenario of using VoCore as an accesspoint combined with a NAT'ing router.

I went a little further and installed some nice to have packages like openssh-sftp-server, nano, htop, ip, etc. However, in order to do this, I first had to fix /etc/opkg.conf:

...
#src/gz cheese_base http://downloads.openwrt.org/snapshots/trunk/ramips/packages/base
#src/gz cheese_luci http://downloads.openwrt.org/snapshots/trunk/ramips/packages/luci
src/gz chaos_calmer_base http://downloads.openwrt.org/snapshots/trunk/ramips/generic/packages/base/
src/gz chaos_calmer_luci http://downloads.openwrt.org/snapshots/trunk/ramips/generic/packages/luci/
src/gz chaos_calmer_management http://downloads.openwrt.org/snapshots/trunk/ramips/generic/packages/management/
src/gz chaos_calmer_packages http://downloads.openwrt.org/snapshots/trunk/ramips/generic/packages/packages/
src/gz chaos_calmer_routing http://downloads.openwrt.org/snapshots/trunk/ramips/generic/packages/routing/
src/gz chaos_calmer_telephony http://downloads.openwrt.org/snapshots/trunk/ramips/generic/packages/telephony/

After that I could install the extra packages by running the following:

opkg update
opkg install openssh-sftp-server
opkg install nano
opkg install htop
opkg install ip

Also, I recommend disabling Luci, as it is buggy, and a security concern:

rm /www/cgi-bin/luci
echo "A private box" > /www/index.html

Wednesday, August 13, 2014

A simple TCP proxy forwarder in .NET

Here's a way of doing a super simple TCP proxy in C#.

Warning: this should only be used for testing purposes, as it will leak threads.

using System;
using System.Net;
using System.Net.Sockets;
using System.Threading;

class Program
{
    static void ProxyStream(string stream1name, NetworkStream stream1, string stream2name, NetworkStream stream2)
    {
        var buffer = new byte[65536];

        try
        {
            while (true)
            {
                var len = stream1.Read(buffer, 0, 65536);
                stream2.Write(buffer, 0, len);
            }
        }
        catch (Exception)
        {
            Console.WriteLine("Stream from " + stream1name + " to " + stream2name + " closed");
        }
    }

    static void Main(string[] args)
    {
        if (args.Length != 3)
        {
            Console.WriteLine("Usage: program.exe localport remoteServerHost remoteServerPort");
            Console.WriteLine("Example: program.exe 13389 10.1.2.3 3389");
            return;
        }

        var localPort = int.Parse(args[0]);
        var remoteServerHost = args[1];
        var remoteServerPort = int.Parse(args[2]);

        var l = new TcpListener(IPAddress.Any, localPort);
        l.Start();
        while (true)
        {
            var client1 = l.AcceptTcpClient();
            var remoteAddress = (client1.Client.RemoteEndPoint as IPEndPoint).Address.ToString();
            Console.WriteLine("Accepted session from " + remoteAddress);
            var client2 = new TcpClient(remoteServerHost, remoteServerPort);
            Console.WriteLine("Created connection to " + remoteServerHost + ":" + remoteServerPort);

            new Thread(() => { ProxyStream(remoteAddress, client1.GetStream(), remoteServerHost, client2.GetStream()); }).Start();
            new Thread(() => { ProxyStream(remoteServerHost, client2.GetStream(), remoteAddress, client1.GetStream()); }).Start();
        }
    }
}

Or, if you need this from PowerShell, I would suggest wrapping it (as threads in PowerShell are painful):
$source = '
using System;
using System.Net;
using System.Net.Sockets;
using System.Threading;

class Program
{
    static void ProxyStream(string stream1name, NetworkStream stream1, string stream2name, NetworkStream stream2)
    {
        var buffer = new byte[65536];

        try
        {
            while (true)
            {
                var len = stream1.Read(buffer, 0, 65536);
                stream2.Write(buffer, 0, len);
            }
        }
        catch (Exception)
        {
            Console.WriteLine("Stream from " + stream1name + " to " + stream2name + " closed");
        }
    }

    static void Main(string[] args)
    {
        if (args.Length != 3)
        {
            Console.WriteLine("Usage: program.exe localport remoteServerHost remoteServerPort");
            Console.WriteLine("Example: program.exe 13389 10.1.2.3 3389");
            return;
        }

        var localPort = int.Parse(args[0]);
        var remoteServerHost = args[1];
        var remoteServerPort = int.Parse(args[2]);

        var l = new TcpListener(IPAddress.Any, localPort);
        l.Start();
        while (true)
        {
            var client1 = l.AcceptTcpClient();
            var remoteAddress = (client1.Client.RemoteEndPoint as IPEndPoint).Address.ToString();
            Console.WriteLine("Accepted session from " + remoteAddress);
            var client2 = new TcpClient(remoteServerHost, remoteServerPort);
            Console.WriteLine("Created connection to " + remoteServerHost + ":" + remoteServerPort);

            new Thread(() => { ProxyStream(remoteAddress, client1.GetStream(), remoteServerHost, client2.GetStream()); }).Start();
            new Thread(() => { ProxyStream(remoteServerHost, client2.GetStream(), remoteAddress, client1.GetStream()); }).Start();
        }
    }
}

'
Add-Type `
    -TypeDefinition $source `
    -Language CSharp `
    -OutputAssembly 'c:\windows\temp\tcpproxy.exe' `
    -OutputType 'ConsoleApplication'

Tuesday, August 05, 2014

Command prompt running as NT AUTHORITY\Network Service

Here's a convenient way to get a command prompt running as Network Service. This is useful for troubleshooting authentication issues for services running as Network Service.

Get Psexec from http://live.sysinternals.com/psexec.exe.

Run:

psexec -u "NT AUTHORITY\Network Service" -i cmd

Or, if you prefer PowerShell:

psexec -u "NT AUTHORITY\Network Service" -i powershell

Or, if you prefer PowerShell, and a bigger than standard window with some distinguishable color:

psexec -u "NT AUTHORITY\Network Service" -i powershell -noexit "cd c:\ ; mode con:cols=170 lines=60 ; (Get-Host).UI.RawUI.BufferSize = New-Object System.Management.Automation.Host.Size(170,3000) ; (Get-Host).UI.RawUI.BackgroundColor='DarkCyan' ; clear"



WCF net.tcp test client in PowerShell

Here's a convenient way of creating a WCF net.tcp client for a quick test. It uses PowerShell to compile C# code to an exe on the fly. Note that the interface can be partial (only containing the method you want to call).
$source = '
    using System;
    using System.ServiceModel;

    [ServiceContract(Namespace = "http://example.com/SomeSchema")]
    public interface ISomeService
    {
        [OperationContract]
        bool SomeMethod();
    }

    public class Wcftest
    {
        public static void Main(string[] args)
        {
            var binding = new NetTcpBinding();
            var address = new EndpointAddress("net.tcp://" + args[0] + ":808/SomeService");

            var factory = new ChannelFactory<ISomeService>(binding, address);
            var proxy = factory.CreateChannel();

            Console.WriteLine(proxy.SomeMethod());
        }
    }
'
Add-Type `
    -ReferencedAssemblies 'System.ServiceModel.dll' `
    -TypeDefinition $source `
    -Language CSharp `
    -OutputAssembly 'c:\windows\temp\wcftest.exe' `
    -OutputType 'ConsoleApplication'

c:\windows\temp\wcftest.exe "example.com"
del c:\windows\temp\wcftest.*

Saturday, June 07, 2014

Simple web UI for managing Libvirt / KVM

When looking for a simple web interface to create / start / stop / delete VMs, I was only able to find systems that seemed overkill for my needs. I wanted something very minimal, where I wouldn't have to install and keep too many libraries up to date. I therefore wrote a simple Python CGI script and a few helper scripts to do the actual privileged operations, to be called via sudo. The code is available here on Github.