Jon's FOSS Blog

Anything networking, programming, crypto and security related

Fedora ARM Image Installer (FAII)

So my third "git-worthy" project is called the Fedora ARM Image Installer. It will basically allow one to "easily" convert an SD-Card into a bootable ARM media device. It is written in Python (2 & 3 for Linux & Windows) and it is based on the PyQt4 GUI framework giving it a more native feel for each platform. Below are some screenshots and links!

Note: To download the binary zip file, make sure to select the "raw" link beside it
Note: To run this script, right click on the .exe file and select "Run as Administrator"

Windows Binary
Linux Source

Wiki: http://fedoraproject.org/wiki/Fedora_ARM_Installer

Smarter Fedora Build Process (Styrene)

Too much code to post here but you can check out the source via git. This project will hopefully allow for a smarter build process to take place when starting from the beginning. It should allow one to intelligently determine which packages need to be built first (if it has 0 dependencies or all of its dependencies already built). You can browse the source and diffs with the URL below:

http://git.fedorahosted.org/git/?p=arm.git;a=summary

Edit: There is a basic SOP page for Styrene if you visit the link below:

http://zenit.senecac.on.ca/wiki/index.php/Styrene

Mini-Koji (Moji) Build System

Edit: The length of code was too much so I posted direct links to the source code in git below

https://fedorahosted.org/arm/browser/moji/moji

http://git.fedorahosted.org/git/?p=arm.git;a=blob_plain;f=moji/moji;hb=HEAD

Edit 2: Link to the wiki page for Moji

https://fedoraproject.org/wiki/Moji

Fedora Losing My WiFi Inet…

So Fedora has been disconnecting me a lot lately from my home wifi and I think it’s because I have disabled a lot of background services that I don’t need. Anyway, I’m trying something new:

yum remove NetworkManager
mkdir /etc/wifi
wpa_passphrase "your_ssid_here" > /etc/wifi/home.conf

Run this script as root when wanting to connect to wifi (assumes the wlan0 interface):

#!/bin/bash
pkil=`which killall`
intf=`which ifconfig`
scan=`which iwlist`
wpas=`which wpa_supplicant`
dhcp=`which dhclient`
ifce="wlan0"
while true
do
	ping -c 1 google.ca > /dev/null 2>&1
	if [ $? -eq 0 ]
	then
		sleep 10
		continue
	fi
	for file in /etc/wifi/*
	do
		$intf "$ifce" up
		ssid=`cat $file | grep -i 'ssid' | sed -e 's/^[ \t]*ssid="//g' -e 's/"[ \t]*$//g'`
		exis=`$scan "$ifce" scan | grep -i "$ssid"`
		if [ "$exis" != "" ]
		then
			echo "[`date`] connecting to [$ssid]..."
			$pkil -9 wpa_supplicant > /dev/null 2>&1
			$pkil -9 dhclient > /dev/null 2>&1
			$intf "$ifce" up
			$wpas -Dwext -i "$ifce" -c "$file" > /dev/null 2>&1 &
			$dhcp "$ifce" > /dev/null 2>&1 &
			break
		fi
	done
	sleep 10
done

Bored And Off Topic!

Just wanted to see how many lines of Python it took me to make a generalized password bruteforce script…

import time

slst = "abcdefghijklmnopqrstuvwxyz"
slen = (len(slst) - 1)
dwrd = [0]
dlen = 1

numb = 0
last = time.time()
wait = 2

while (1):
	# process password
	i = 0
	s = ""
	while (i < dlen):
		s = (s + slst[dwrd[i]])
		i = (i + 1)
	# print stats
	numb = (numb + 1)
	pres = time.time()
	if ((pres - last) >= wait):
		print("pw=[%s] @ [%d p/s]" % (s, numb / wait))
		numb = 0
		last = pres
	# overflow increase
	dwrd[dlen - 1] = (dwrd[dlen - 1] + 1)
	i = (dlen - 1)
	u = 1
	while (i > -1):
		if (dwrd[i] > slen):
			dwrd[i] = 0
			if ((i - 1) > -1):
				dwrd[i - 1] = (dwrd[i - 1] + 1)
		else:
			u = 0
		i = (i - 1)
	# length expansion
	if (u == 1):
		i = 0
		while (i < dlen):
			dwrd[i] = 0
			i = (i + 1)
		dwrd.append(0)
		dlen = (dlen + 1)

Formatting Flat Files As Block Devices

Here’s a small shell script based on dd’s output which helps to partition a flat file, split it up into its respective partitions so they can be formatted and put them all back together again.

#!/bin/bash

if [ "${1}" == "c" ]
then
	if [ "${3}" == "" ]
	then
		echo "Usage: $0 $1 <filename> <filesize>"
		exit 1
	fi
	echo "Creating new file [${2}]..."
	dd if=/dev/zero of=${2} bs=${3}G count=1 > /dev/null 2>&1
	echo "Partition the new flat file ( fdisk ${2} )"
	echo
fi

if [ "${1}" == "s" ]
then
	if [ "${2}" == "" ]
	then
		echo "Usage: $0 $1 <filename>"
		exit 1
	fi
	unit=`fdisk -l "${2}" | grep -i '^Units' | sed -e 's/^.* \([0-9][0-9]*\) bytes.*$/\1/g'`
	lase="-1"
	numb=0
	fdisk -l "${2}" | sed -e 's/^[ \t]*//g' -e 's/\*//g' | grep -i "^${2}[0-9][0-9]*" | while read line
	do
		curb=`echo "${line}" | awk '{ print $2 }'`
		cure=`echo "${line}" | awk '{ print $3 }'`
		let size="${cure} - ${curb} + 1"
		let diff="${curb} - ${lase} - 1"
		if [ ${diff} -gt 0 ]
		then
			let endi="${curb} - 1"
			let skip="${lase} + 1"
			echo "[${numb}] Unused space [${skip} - ${endi}] [${diff} blocks]..."
			dd if=${2} bs=${unit} skip=${skip} count=${diff} of=${2}${numb} > /dev/null 2>&1
			let numb="${numb} + 1"
		fi
		echo "[${numb}] Carving partition [${curb} - ${cure}] [${size} blocks]..."
		dd if=${2} bs=${unit} skip=${curb} count=${size} of=${2}${numb} > /dev/null 2>&1
		let numb="${numb} + 1"
		lase="${cure}"
	done
	fdisk -l "${2}" | sed -e 's/^[ \t]*//g' -e 's/\*//g' | grep -i "^${2}[0-9][0-9]*" | tail -n 1 | while read line
	do
		endi=`echo "${line}" | awk '{ print $3 }'`
		let rest="${endi} + 1"
		numb="9"
		echo "[${numb}] Copying ending [${rest} - <end>]..."
		dd if=${2} bs=${unit} skip=${rest} of=${2}${numb} > /dev/null 2>&1
	done
	echo
	echo "Create any filesystem needed ( mkfs.* ${2}[0-9] )"
	echo "Mount any filesystem needed ( mount -o loop ${2}[0-9] /mnt/tmp[0-9] )"
	echo "Copy any files needed ( cp -r source/* /mnt/tmp[0-9]/ )"
	echo "Unmount any filesystem needed ( umount /mnt/tmp[0-9] )"
	echo
fi

if [ "${1}" == "j" ]
then
	if [ "${2}" == "" ]
	then
		echo "Usage: $0 $1 <filename>"
		exit 1
	fi
	echo "Writing to file [${2}.join]..."
	cat ${2}[0-9]* > ${2}.join
	echo
fi

Simple Monitoring Shell Script & PHP Page

So, you would run this on a Koji builder:

monitor.sh

#!/bin/bash

while true
do
	filename="/tmp/stat.txt"
	
	machname=`hostname | strings | tr '\n' ' '`
	machrels=`cat /etc/fedora-release | sed -e 's/release//g' -e 's/[ \t]*([^)]*)[ \t]*//g' | strings | tr '\n' ' '`
	machvers=`uname -r | strings | tr '\n' ' '`
	
	machipv4=`ifconfig | grep -i 'inet[ :]' | sed -e 's/addr://g' | awk '{ print $2 }' | strings | tr '\n' ' '`
	machipv6=`ifconfig | grep -i 'inet6[ :]' | sed -e 's/addr://g' | awk '{ print $2 }' | strings | tr '\n' ' '`
	dnsserve=`cat /etc/resolv.conf | grep '^nameserver' | sed -e 's/^[^0-9]*//g' | strings | tr '\n' ' '`
	gatewaya=`netstat -nr | sed -e 's/default/0.0.0.0/g' | grep -i '^0.0.0.0' | awk '{ print $2 }' | strings | tr '\n' ' '`
	pingcomd=`ping -c 1 google.ca 2>&1 | grep -i '0% packet loss'`
	if [ "$pingcomd" != "" ] ; then netusage="Yes" ; else netusage="No" ; fi
	
	cpuusage=`top -bn 3 2>&1 | grep -i '^cpu' | sed -e 's/^.*[ \t][ \t]*\([^%]*%\)[^,]*\(us\),.*$/\1\2/g' | sort -nr | head -n 1 | strings | tr '\n' ' '`
	hddusage=`df -h / | grep -iv '^file' | awk '{ print "/("$6")="$4"/"$2"(free)" }' | strings | tr '\n' ' '`
	ramusage=`free -m | grep -i '^mem' | awk '{ print $4"M/"$2"M(free)" }' | strings | tr '\n' ' '`
	swapused=`free -m | grep -i '^swap' | awk '{ print $4"M/"$2"M(free)" }' | strings | tr '\n' ' '`
	
	mockfold=`(df -h /var/lib/mock/ | grep -iv '^file' | awk '{ print "/var/lib/mock("$6")="$4"/"$2"(free)" }' ; ls -al /var/lib/mock/ 2> /dev/null | grep -i ' \.$' | sed -e 's/^.\(...\)\(...\)\(...\).[ \t]*[^ \t]*[ \t]*\([^ \t]*\)[ \t]*\([^ \t]*\).*$/\1(\4):\2(\5):\3(o)/g') | strings | tr '\n' ' '`
	kojimoni=`service kojid status | grep -Ei '(active|running)'`
	if [ "$kojimoni" == "" ] ; then kojistat="Not running" ; else kojistat="Running" ; fi
	pkgsvers=`rpm -q koji koji-builder mock rpm yum | strings | tr '\n' ' '`
	
	#echo "$machname" > $filename
	date > $filename
	echo "$machrels" >> $filename
	echo "$machvers" >> $filename
	
	echo "$machipv4" >> $filename
	echo "$machipv6" >> $filename
	echo "$dnsserve" >> $filename
	echo "$gatewaya" >> $filename
	echo "$netusage" >> $filename
	
	echo "$cpuusage" >> $filename
	echo "$hddusage" >> $filename
	echo "$ramusage" >> $filename
	echo "$swapused" >> $filename
	
	echo "$kojistat" >> $filename
	echo "$mockfold" >> $filename
	echo "$pkgsvers" >> $filename
	
	curl -F "pass=qwerty" -F "name=$machname" -F "data=@$filename" http://hongkong.proximity.on.ca/~jchiappetta/monitor.php
	sleep 300
done

And you run this on the server-side:

monitor.php

<?php
	/* CREATE TABLE stat (name VARCHAR(256), data VARCHAR(4096)); */
	
	function safe($inpt)
	{
		$srch = array("<", ">", "&", ";", "'", "\"", "\\");
		$inpt = trim($inpt);
		$inpt = str_replace($srch, "", $inpt);
		
		return $inpt;
	}
	
	if ($_POST["pass"] == "qwerty")
	{
		if (isset($_POST["name"]) and isset($_FILES["data"]))
		{
			$fobj = fopen($_FILES["data"]["tmp_name"], "r");
			$_POST["data"] = fread($fobj, 4000);
			fclose($fobj);
			
			$_POST["name"] = safe($_POST["name"]);
			$_POST["data"] = safe($_POST["data"]);
			
			$dobj = new PDO("sqlite:monitor.db");
			$dobj->exec("DELETE FROM stat WHERE name = '".$_POST["name"]."';");
			$dobj->exec("INSERT INTO stat VALUES ('".$_POST["name"]."', '".$_POST["data"]."');");
			$dobj = NULL;
		}
		
		die;
	}
	
	$dobj = new PDO("sqlite:monitor.db");
	$resl = $dobj->query("SELECT * FROM stat ORDER BY name;");
	$rows = array();
	
	foreach ($resl as $rowd)
	{
		$temp = array();
		array_push($temp, safe($rowd["name"]));
		$data = explode("\n", $rowd["data"]);
		
		foreach ($data as $info)
		{
			array_push($temp, safe($info));
		}
		
		array_push($rows, $temp);
	}
	
	$dobj = NULL;
?>

<html>
	<head>
		<title>Monitor</title>
		
		<style>
			body
			{
				background: #E6E6FA;
				font-family: Courier;
				font-size: 0.75em;
			}
			
			a
			{
				text-decoration: none;
			}
			
			th
			{
				text-align: left;
			}
			
			.info
			{
				color: #000080;
			}
			
			.inet
			{
				color: #006400;
			}
			
			.syst
			{
				color: #E56717;
			}
			
			.koji
			{
				color: #8B0000;
			}
			
			.hide
			{
				display: none;
			}
		</style>
		
		<script>
			function more(name)
			{
				var x, temp;
				var objl = document.getElementsByClassName(name);
				
				for (x = 0; x < objl.length; ++x)
				{
					if (objl[x].className.match(/^.*main.*$/))
					{
						continue;
					}
					
					else if (objl[x].className.match(/^.*hide.*$/))
					{
						temp = objl[x].className.replace(/hide/g, "");
						objl[x].className = temp;
					}
					
					else
					{
						objl[x].className = (objl[x].className + " hide");
					}
				}
			}
			
			function init()
			{
				var x;
				var tabl = document.getElementById("tabl");
				
				var tout = (10 * 60), numb = 0, temp;
				var dtls, dtlo = new Date(), dtrs, dtro;
				
				for (x = 1; x < tabl.rows.length; ++x)
				{
					dtro = new Date(tabl.rows[x].cells[1].innerHTML);
					dtls = parseInt(dtlo.getTime() / 1000);
					dtrs = parseInt(dtro.getTime() / 1000);
					
					if ((dtls - tout) >= dtrs)
					{
						temp = tabl.rows[x].cells[0].innerHTML;
						temp = ("<font color='red'>" + temp + "</font>");
						tabl.rows[x].cells[0].innerHTML = temp;
						++numb;
					}
				}
				
				document.title = ("Monitor [" + numb + "] [" + dtlo.getHours() + ":" + dtlo.getMinutes() + "]");
				
				var elel = document.getElementsByClassName("list");
				
				for (x = 0; x < elel.length; ++x)
				{
					temp = elel[x].innerHTML;
					temp = temp.replace(/ /g, "<br />");
					elel[x].innerHTML = temp;
				}
			}
		</script>
		
		<meta http-equiv="refresh" content="900">
	</head>
	
	<body onload="init();">
		<table id="tabl" width="100%">
			<tr>
				<th class="info main">Name <a href="javascript:more('info');">[i]</a></th>
				<th class="info hide">Time</th>
				<th class="info hide">Release</th>
				<th class="info hide">Kernel</th>
				<th class="inet hide">IPv4</th>
				<th class="inet hide">IPv6</th>
				<th class="inet hide">DNS</th>
				<th class="inet hide">Gateway</th>
				<th class="inet main">Inet <a href="javascript:more('inet');">[i]</a></th>
				<th class="syst hide">CPU</th>
				<th class="syst main">Disk <a href="javascript:more('syst');">[i]</a></th>
				<th class="syst hide">RAM</th>
				<th class="syst hide">Swap</th>
				<th class="koji main">Koji <a href="javascript:more('koji');">[i]</a></th>
				<th class="koji list hide">Mock</th>
				<th class="koji list hide">Pkgs</th>
			</tr>
			
			<?php
				foreach ($rows as $rowd)
				{
					echo ("<tr>"."\n");
					echo ("<td class=\"info main\">".$rowd[0]."</td>"."\n");
					echo ("<td class=\"info hide\">".$rowd[1]."</td>"."\n");
					echo ("<td class=\"info hide\">".$rowd[2]."</td>"."\n");
					echo ("<td class=\"info hide\">".$rowd[3]."</td>"."\n");
					echo ("<td class=\"inet hide\">".$rowd[4]."</td>"."\n");
					echo ("<td class=\"inet hide\">".$rowd[5]."</td>"."\n");
					echo ("<td class=\"inet hide\">".$rowd[6]."</td>"."\n");
					echo ("<td class=\"inet hide\">".$rowd[7]."</td>"."\n");
					echo ("<td class=\"inet main\">".$rowd[8]."</td>"."\n");
					echo ("<td class=\"syst hide\">".$rowd[9]."</td>"."\n");
					echo ("<td class=\"syst main\">".$rowd[10]."</td>"."\n");
					echo ("<td class=\"syst hide\">".$rowd[11]."</td>"."\n");
					echo ("<td class=\"syst hide\">".$rowd[12]."</td>"."\n");
					echo ("<td class=\"koji main\">".$rowd[13]."</td>"."\n");
					echo ("<td class=\"koji list hide\">".$rowd[14]."</td>"."\n");
					echo ("<td class=\"koji list hide\">".$rowd[15]."</td>"."\n");
					echo ("</tr>"."\n");
				}
			?>
		</table>
	</body>
</html>

[offtopic] iTunes Library Scripts

So I was trying to get my pc laptop setup for fudcon which meant a triple boot setup between windows, ubuntu and fedora. I had some troubles importing various important information about my music within iTunes.

Here is a script to remove duplicate songs in an iTunes folder:

import hashlib
import os
import re
import sys

def hash(fnam):
	fobj = open(fnam, "r")
	hobj = hashlib.sha256()
	
	while (1):
		data = fobj.read(2**20)
		
		if (not data):
			break
		
		hobj.update(data)
	
	return hobj.hexdigest()

fdic = {}

while (1):
	file = sys.stdin.readline()
	
	if (not file):
		break
	
	file = file.strip()
	uniq = hash(file)
	
	if (uniq in fdic.keys()):
		print("removing:",file)
		os.unlink(file)
	
	else:
		print("found:",file)
		fdic[uniq] = file

This script attempts to merge an old iTunes library xml file with a newly imported one. The result is a merged iTunes library xml file that can then be re-imported into iTunes thus restoring some various meta-data about your music. Note: Before you re-import the merged xml playlist file, make sure you delete the current one and disable the check-box stating to copy songs into the media folder.

import os
import re
import sys

if (len(sys.argv) < 3):
	print("Usage: %s <source> <merge>" % (sys.argv[0]))
	sys.exit(0)

def outp(ordr, dict, line):
	for item in ordr:
		sys.stdout.write(dict[item][1])
	
	sys.stdout.write(line)
	sys.stdout.flush()

def xmlr(fnam, sdic={}):
	alen = len(sys.argv)
	slen = len(sdic.keys())
	xord = []; xdic = {}
	xobj = open(fnam, "r")
	
	xdat = {}
	
	while (1):
		xlin = xobj.readline()
		
		if (not xlin):
			break
		
		slin = xlin.strip("\0\t\r\n ")
		xreg = re.match("^<key>([^<]+)</key>(<[^>]+>[^<]+<[^>]+>)$", slin)
		
		try:
			xkey = (xdic["Artist"][0] + xdic["Album"][0] + xdic["Name"][0])
		
		except:
			xkey = ""
		
		if (slin == "<dict>"):
			if (slen > 0):
				outp(xord, xdic, xlin)
			
			xord = []; xdic = {}
		
		elif (xreg):
			if (xreg.group(1) not in xord):
				xord.append(xreg.group(1))
			
			xdic[xreg.group(1)] = [xreg.group(2), xlin]
		
		elif (slin == "</dict>"):
			if (slen < 1):
				xdat[xkey] = xdic
			
			else:
				for x in range(3, alen):
					try:
						xdic[sys.argv[x]] = sdic[xkey][sys.argv[x]]
						
						if (sys.argv[x] not in xord):
							xord.append(sys.argv[x])
					
					except:
						#print("error:",sys.exc_info())
						pass
				
				outp(xord, xdic, xlin)
			
			xord = []; xdic = {}
		
		else:
			if (slen > 0):
				outp(xord, xdic, xlin)
			
			xord = []; xdic = {}
	
	return xdat

sdat = xmlr(sys.argv[1])
ddat = xmlr(sys.argv[2], sdic=sdat)

Here’s an example of how to use the command:

python.exe /cygdrive/c/Users/jon/Desktop/itml.py /cygdrive/g/tmp/itunes/iTunes\ Music\ Library0.xml /cygdrive/g/tmp/itunes/iTunes\ Music\ Library.xml 'Date Added' 'Play Count' | unix2dos.exe | tee /cygdrive/g/tmp/itunes/iTunes\ Music\ Library2.xml && cp /cygdrive/g/tmp/itunes/iTunes\ Music\ Library2.xml /cygdrive/g/tmp/itunes/iTunes\ Music\ Library3.xml

[updated] F15 Koji Que Script

Here it is, hopefully it works a bit better!

#!/bin/bash
export x=1
export l=`find ./f15srpms -type f | grep -i '\.src\.rpm' | wc -l`
koji list-tagged dist-f15 > /tmp/pkoji.txt
find ./f15srpms -type f | sort -R | grep -i '\.src\.rpm' > /tmp/pkgsl.txt
while true
do
	while true
	do
		ak list-tagged dist-f15 > /tmp/akoji.txt
		ak list-tasks --mine --quiet | grep '^[0-9]' | grep -Ei ' (open|free) .* build' > /tmp/tasks.txt
		#echo "number of our tasks == `cat /tmp/tasks.txt | wc -l`"
		n=`cat /tmp/tasks.txt | wc -l`
		if [ $n -ge 10 ]
		then
			break
		fi
		p=`cat /tmp/pkgsl.txt | head -n "$x" | tail -n 1`
		q=`basename "$p" | sed -e 's/-[^-]*-[^-]*$//'`
		let x="($x % $l) + 1"
		#echo "checking pkg [$p] name [$q] not built on (akoji) and built on (pkoji)"
		c=`cat /tmp/akoji.txt /tmp/tasks.txt | grep -i "$q"`
		if [ "$c" != "" ]
		then
			continue
		fi
		c=`cat /tmp/pkoji.txt | grep -i "$q"`
		if [ "$c" == "" ]
		then
			continue
		fi
		echo "queing [$p] position [$x]"
		ak build dist-f15 "$p" --nowait --background
	done
	sleep 60
done

[off-topic] Fighting Governments — DNS Re-Implemented

The U.S. government is taking down websites using DNS poisoning/hijacking methods on pages that are claimed to be infringing on copyright law. I have re-written a *really* basic DNS server which re-implements DNS forwarding/proxying, DNS caching and DNS un-blacklisting of A/IN/IPv4 records. Basically, if one were to run their own DNS server (like the one below) and maintain a simple list of government-poisoned IP addresses for it, the DNS server would be able to provide (previously expired but still good) IPv4 addresses for the blocked site. This could essentially allow one to re-access a now blacklisted website.

Here is a screen shot of my computer using this basic DNS server to visit slashdot:

$ host slashdot.org
slashdot.org has address 216.34.181.45
slashdot.org mail is handled by 10 mx.sourceforge.net.

And here is what it would look like if it were taken down via DNS poisoning:

$ host slashdot.org
slashdot.org has address 74.81.170.110
slashdot.org has address 216.34.181.45
slashdot.org mail is handled by 10 mx.sourceforge.net.

Once this happens, all one has to do now is append the newly offending IP address to the DNS server’s black list text file like so:

# cat dnsb.txt
74.81.170.110

And if you perform another DNS request to the same (custom) DNS server, you get the last cached answers bringing you back to slashdot:

$ host slashdot.org
slashdot.org has address 216.34.181.45
slashdot.org mail is handled by 10 mx.sourceforge.net.

The code below is simply proof-of-concept software and should *NOT* be used for production as I have implemented everything from scratch here and know very little about how DNS really works (i.e. message compression).

import os
import re
import socket
import sqlite3
import sys
import time

sqlo = sqlite3.connect("dnsd.db")
sqlc = sqlo.cursor()

def fixs(inpt):
	outp = ""
	
	for letr in inpt:
		if (ord(letr) < 32):
			outp += "."
		
		else:
			outp += letr
	
	return outp

def rslv():
	nlst = []
	fobj = open("/etc/resolv.conf", "r")
	
	dnsl = fobj.readlines()
	
	for dnse in dnsl:
		item = dnse.strip("\0\t\r\n ")
		regx = re.match("^nameserver[ \t]*(.*)$", item)
		
		if (regx):
			addr = regx.group(1)
			nlst.append(addr)
	
	return nlst

def forw(addr, data):
	resp = ""
	serv = (addr, 53)
	nobj = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
	
	try:
		nobj.settimeout(5)
		nobj.sendto(data, serv)
		resp = nobj.recv(2**20)
	
	except:
		pass
	
	try:
		nobj.close()
	
	except:
		pass
	
	return resp

def answ(data, deet=False):
	# http://www.ietf.org/rfc/rfc1035.txt
	
	requ = 13
	null = (requ + data[requ:].find("\0"))
	dtyp = (null + 5)
	dlen = (dtyp + 10)
	
	size = len(data)
	name = fixs(data[requ:null])
	begi = -1
	endi = -1
	ansl = []
	
	while ((dlen + 1) < size):
		dsiz = ((ord(data[dlen]) << 8) + ord(data[dlen + 1]))
		dsig = (dtyp + 4)
		
		if (((dlen + 5) < size) and (data[dtyp:dsig] == "\xc0\x0c\x00\x01")):
			if (deet == True):
				if (begi == -1):
					begi = dtyp
				
				else:
					endi = (dlen + 1 + dsiz + 1)
			
			addr = ""
			
			for x in range(2, 2 + 4):
				addr += ("." + str(ord(data[dlen + x])))
			
			ansl.append([name, addr[1:]])
		
		dtyp = (dlen + 1 + dsiz + 1)
		dlen = (dtyp + 10)
	
	if (begi == -1):
		begi = (null + 5)
		endi = begi
	
	if (deet == False):
		return ansl
	
	else:
		return [begi, endi]

def sqle(comd, outp=False):
	global sqlo
	global sqlc
	
	try:
		sqlc.execute(comd)
	
	except:
		pass
	
	if (outp == False):
		sqlo.commit()
	
	else:
		return sqlc.fetchall()

def filt():
	try:
		fobj = open("dnsb.txt", "r")
		
		for line in fobj.readlines():
			addr = line.strip("\0\t\r\n ")
			sqle("DELETE FROM data WHERE addr = '%s';" % (addr))
		
		fobj.close()
	
	except:
		return 0
	
	return 1

def cche(name):
	dbdl = sqle("SELECT * FROM data WHERE name = '%s';" % (name), outp=True)
	outp = []
	
	for dbdi in dbdl:
		adrl = dbdi[1].split(".")
		adrs = ""
		
		for adri in adrl:
			adrs += chr(int(adri))
		
		outp.append([int(dbdi[2]), adrs])
	
	outp.sort()
	outp.reverse()
	
	return outp

def shim(data, adrl):
	hedn = [6, 8]
	payn = answ(data, deet=True)
	
	lead = (payn[0] + 12)
	size = len(adrl)
	
	dlen = (chr((size >> 8) & 0xff) + chr((size >> 0) & 0xff))
	head = (data[:hedn[0]] + dlen + data[hedn[1]:payn[0]])
	
	payl = ""
	
	for adri in adrl:
		payl += (data[payn[0]:lead] + adri[1])
	
	payl += data[payn[1]:]
	
	outp = (head + payl)
	
	# beg: compression offset bypass
	
	outp = (outp[:8] + chr(0) + chr(0) + outp[10:])
	outp = (outp[:10] + chr(0) + chr(0) + outp[12:])
	
	# end: compression offset bypass
	
	# beg: compression offset fix
	'''
	x = 0
	l = len(outp)
	s = ((ord(data[6]) << 8) + ord(data[7]))
	d = ((size - s) * 16)
	
	if (d > 0):
		while ((x + 1) < l):
			o = ((ord(outp[x]) << 8) + ord(outp[x + 1]))
			
			if ((o & 0xff00) == 0xc000):
				o = (o & 0x00ff)
				
				if (o > 0x0c):
					o = (o + d)
					outp = (outp[:x] + chr((o >> 8) & 0xff) + chr((o >> 0) & 0xff) + outp[x + 2:])
			
			x = (x + 2)
	'''
	# end: compression offset fix
	
	return outp

def debg(addr, requ, answ):
	adrl = addr.split(".")
	adrl[3] = "x"
	prio = ""
	
	for letr in answ:
		prio += ("." + str(ord(letr)))
	
	print("[%s] requ [%s] answ [%s, ...]" % (".".join(adrl), requ, prio[1:]))

def serv():
	snam = ("", 53)
	sobj = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
	
	sobj.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
	sobj.bind(snam)
	
	while (1):
		(data, addr) = sobj.recvfrom(2**20)
		rlvl = rslv()
		
		for rlvi in rlvl:
			dnsr = forw(rlvi, data)
			
			if (dnsr):
				resl = answ(dnsr)
				
				if (len(resl) > 0):
					for resi in resl:
						dnsq = re.sub("[^0-9A-Za-z\.\-]", "", resi[0])
						dnsa = re.sub("[^0-9\.]", "", resi[1])
						epch = str(int(time.time()))
						
						dbdl = sqle("SELECT * FROM data WHERE name = '%s' AND addr = '%s';" % (dnsq, dnsa), outp=True)
						
						if (len(dbdl) < 1):
							sqle("INSERT INTO data VALUES ('%s', '%s', '0');" % (dnsq, dnsa))
						
						sqle("UPDATE data SET time = '%s' WHERE name = '%s' AND addr = '%s';" % (epch, dnsq, dnsa))
					
					filt()
					dbdl = cche(dnsq)
					
					if (len(dbdl) > 0):
						debg(addr[0], resl[0][0], dbdl[0][1])
						#a=open("a","w");a.write(dnsr);a.close();
						dnsr = shim(dnsr, dbdl)
						#b=open("b","w");b.write(dnsr);b.close();
				
				sobj.sendto(dnsr, addr)
				break

def priv():
	# get username & os.setgid() & os.setuid()
	pass

if (__name__ == "__main__"):
	sqle("CREATE TABLE data (name VARCHAR(256), addr VARCHAR(256), time VARCHAR(256));")
	priv()
	serv()

Attempting To Finally Contribute

So I haven’t had much to talk about lately due the amount of work given for the last few weeks remaining in school and the building of Fedora 15 for ARMv5 and ARMv7. However, in my spare time, I’ve been trying to contribute positively to the Koji Build System project by submitting mailing list items containing source code unified diff patches. Most of my posts/changes contain feature enhancements requested by other people that I found to be somewhat interesting to code. If you’re interested in viewing the mailing list items, the links can be found below:

Hosts-Page Colour Highlight: [ Ticket ] [ Patch ]
Hosts-Page “Life-Line” Links: [ Ticket ] [ Patch ]
Host-Info Latest-Builds Links: [ Ticket ] [ Patch ]
Koji-Client watch-logs “tail”: [ Ticket ] [ Patch ]
Koji-Hub RPMTAG_SIGSHA2 Hashing: [ Ticket ] [ Patch ]

Really Short On RPM

After many yum-installs and a custom compile of berkeley-db, here’s the command to configure rpms source:

./configure --with-external-db --without-lua CPPFLAGS="-I/usr/include/nspr4 -I/usr/include/nss3 -I/usr/local/BerkeleyDB.5.2/include" LDFLAGS="-L/usr/local/BerkeleyDB.5.2/lib"
Follow

Get every new post delivered to your Inbox.