Posted by Matteo Mattei / 25th October 2011
This simple piece of code shows how to extract/decompress a u-boot multi-file image created with mkimage using Python. The image format is pretty simple:
64 bytes of image header.
4 bytes for the size of first image.
4 bytes for the size of second image.
...
4 bytes of zeros for termination.
image1.
image2.
...
You need to remember also that each image is padded to 4 bytes.
#!/usr/bin/env python
import sys
def toNumber(buf):
""" Convert string in number """
size = 0
for b in buf: size=size*256+ord(b)
return size
if len(sys.argv)!=2:
sys.stdout.write('Usage %s uboot_image_file\n' % sys.argv[0])
sys.exit(1)
f = open(sys.argv[1],'rb')
f.seek(64) # skip image header
parts = []
# get file size of all images
while True:
buf = f.read(4)
size = toNumber(buf)
if size==0: break
parts.append(size)
i = 0
for size in parts:
pattern = 'file%d.img' % i
p = open(pattern, 'wb')
buf = f.read(size)
p.write(buf)
p.close()
if size%4 != 0:
# 4 byte padding
f.read(4-(size%4))
i+=1
f.close()
Posted by Matteo Mattei / 28th August 2011
In these days I started studying PySide. After some days spent in reading lot of stuff, I thought that a real example could be useful for who intends to start learning PySide as well. In this example I can show you how you can implement a custom signal (MySignal) together with the usage of threads with QThread.
The following code creates a window with two button: the first starts and stop a thread (MyThread) that runs a batch that prints a point in the stdout every seconds continuously. The second button lets you only start another thread (MyLongThread) that prints an asterisk in the stdout every second for 10 seconds.
This example uses the api version 2 (introduced with PyQt 4.5) to connect signals to slots.
#!/usr/bin/env python2
import sys, time
from PySide.QtGui import *
from PySide.QtCore import *
class MySignal(QObject):
sig = Signal(str)
class MyLongThread(QThread):
def __init__(self, parent = None):
QThread.__init__(self, parent)
self.exiting = False
self.signal = MySignal()
def run(self):
end = time.time()+10
while self.exiting==False:
sys.stdout.write('*')
sys.stdout.flush()
time.sleep(1)
now = time.time()
if now>=end:
self.exiting=True
self.signal.sig.emit('OK')
class MyThread(QThread):
def __init__(self, parent = None):
QThread.__init__(self, parent)
self.exiting = False
def run(self):
while self.exiting==False:
sys.stdout.write('.')
sys.stdout.flush()
time.sleep(1)
class MainWindow(QMainWindow):
def __init__(self, parent=None):
QMainWindow.__init__(self,parent)
self.centralwidget = QWidget(self)
self.batchbutton = QPushButton('Start batch',self)
self.longbutton = QPushButton('Start long (10 seconds) operation',self)
self.label1 = QLabel('Continuos batch')
self.label2 = QLabel('Long batch')
self.vbox = QVBoxLayout()
self.vbox.addWidget(self.batchbutton)
self.vbox.addWidget(self.longbutton)
self.vbox.addWidget(self.label1)
self.vbox.addWidget(self.label2)
self.setCentralWidget(self.centralwidget)
self.centralwidget.setLayout(self.vbox)
self.thread = MyThread()
self.longthread = MyLongThread()
self.batchbutton.clicked.connect(self.handletoggle)
self.longbutton.clicked.connect(self.longoperation)
self.thread.started.connect(self.started)
self.thread.finished.connect(self.finished)
self.thread.terminated.connect(self.terminated)
self.longthread.signal.sig.connect(self.longoperationcomplete)
def started(self):
self.label1.setText('Continuous batch started')
def finished(self):
self.label1.setText('Continuous batch stopped')
def terminated(self):
self.label1.setText('Continuous batch terminated')
def handletoggle(self):
if self.thread.isRunning():
self.thread.exiting=True
self.batchbutton.setEnabled(False)
while self.thread.isRunning():
time.sleep(0.01)
continue
self.batchbutton.setText('Start batch')
self.batchbutton.setEnabled(True)
else:
self.thread.exiting=False
self.thread.start()
self.batchbutton.setEnabled(False)
while not self.thread.isRunning():
time.sleep(0.01)
continue
self.batchbutton.setText('Stop batch')
self.batchbutton.setEnabled(True)
def longoperation(self):
if not self.longthread.isRunning():
self.longthread.exiting=False
self.longthread.start()
self.label2.setText('Long operation started')
self.longbutton.setEnabled(False)
def longoperationcomplete(self,data):
self.label2.setText('Long operation completed with: '+data)
self.longbutton.setEnabled(True)
if __name__=='__main__':
app = QApplication(sys.argv)
window = MainWindow()
window.show()
sys.exit(app.exec_())
For more information you can look at:
QThread documentation: http://doc.qt.nokia.com/latest/qthread.html
PySide signals and slots: http://developer.qt.nokia.com/wiki/Signals_and_Slots_in_PySide
PyQt api 2 on PySide: http://www.pyside.org/docs/pseps/psep-0101.html
Posted by Matteo Mattei / 27th July 2011
If you have root access but you need to run some applications/scripts with some other user credentials you can do it with
su - username -c "command to execute"
But if you need to do it within a C/C++ program you need to follow this procedure:
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <pwd.h>
int main(int argc, char* argv[])
{
if(argc != 3)
{
printf("Usage: %s [USERNAME] [COMMAND]\n",argv[0]);
return 1;
}
char *env[16];
char envc[16][64];
struct passwd *pw = getpwnam(argv[1]);
if(pw==NULL)
{
printf("User %s does not exists!\n",argv[1]);
return 1;
}
sprintf(env[0]=envc[0],"TERM=xterm");
sprintf(env[1]=envc[1],"USER=%s",pw->pw_name);
sprintf(env[2]=envc[2],"HOME=%s",pw->pw_dir);
sprintf(env[3]=envc[3],"SHELL=%s",pw->pw_shell);
sprintf(env[4]=envc[4],"LOGNAME=%s",pw->pw_name);
sprintf(env[5]=envc[5],"PATH=/usr/bin:/bin:/opt/bin");
env[6]=0;
initgroups(argv[1],pw->pw_gid);
setgid(pw->pw_gid);
setuid(pw->pw_uid);
execve(argv[2],NULL,env);
return 0;
}
This is how to compile and execute the above code:
[root@barracuda ~]# gcc mysu.c -o mysu
[root@barracuda ~]# id
uid=0(root) gid=0(root) gruppi=0(root),1(bin),2(daemon),3(sys),4(adm),6(disk),10(wheel),19(log)
[root@barracuda ~]# ./mysu matteo /bin/bash
[matteo@barracuda /root]$ id
uid=1000(matteo) gid=100(users) groups=100(users),3(sys),10(wheel),14(uucp),91(video),92(audio),93(optical),95(storage),96(scanner),97(camera),98(power),108(vboxusers)
The same result could be obtained also in Python with a very little effort:
#!/usr/bin/env python
import sys,pwd,os
pw = pwd.getpwnam(sys.argv[1])
os.initgroups(sys.argv[1],pw.pw_gid)
env={"TERM":"xterm","USER":pw.pw_name,"HOME":pw.pw_dir,"SHELL":pw.pw_shell,"LOGNAME":pw.pw_name,"PATH":"/usr/bin:/bin:/opt/bin"};
os.setgid(pw.pw_gid);
os.setuid(pw.pw_uid);
os.execve(sys.argv[2],[],env);
Posted by Matteo Mattei / 22nd March 2011
Today with my friend Nicola, we were looking in internet for the implementation of the X9.19 algorithm in python. Unfortunately we didn’t find it anywhere so we made it ourself:
#!/usr/bin/env python2
import Crypto.Cipher.DES as des
import Crypto.Cipher.DES3 as des3
def mac_x919(key,data):
while len(data) % 8 != 0:
data += '\x00'
des_key1 = des.new(key[0:8],des.MODE_CBC)
des_key2 = des.new(key[0:8],des.MODE_ECB)
buf = des_key1.encrypt(data)
buf = buf[len(buf)-8:]
buf = des_key2.decrypt(buf)
des3_key = des3.new(key,des3.MODE_ECB)
buf = des3_key.encrypt(buf)
return buf[0:4]
mac = mac_x919('0123456789abcdef','test data to be encrypted')