Have VIM let you know when your lines are too long
April 15, 2010
I stole this from StackOverflow:
highlight OverLength ctermbg=red ctermfg=white guibg=#592929
match OverLength /\%81v.\+/
Looks nice. Subtle, but noticeable.
Using the cert we just created…
February 12, 2010
In the last post, I described how to create a keypair and self-signed certificate. Now, we need to:
- use them to encrypt our traffic and
- allow the user to install the cert in his or her browser.
Here’s how to do this using Twisted. This code creates a page at 8080 that will download the certificate to the user’s browser and a site at 8081 that uses HTTPS. Connect to http://HOSTNAME:8080 to get the cert (your browser will prompt you to install it). Then, you can connect to https://HOSTNAME:8081 and browse securely.
Note that HOSTNAME can’t be ‘localhost’. Not much you can do here – certificates are tied to the actual hostname you use.
This code assumes that the code from that last post is in a module named pki.py, btw.
from twisted.web import server, resource, http
from twisted.internet import reactor, ssl
from twisted.python import log
import sys
from OpenSSL import SSL
from pki import KEY_FILE, CERT_FILE, create_self_signed_cert
def make_ssl_context():
create_self_signed_cert(".")
context = ssl.DefaultOpenSSLContextFactory(KEY_FILE, CERT_FILE)
return context
class HelloWorldPage(resource.Resource):
isLeaf = True
def render_GET(self, request):
return "<html><body><h1>Hello World</h1></body></html>"
class CertPage(resource.Resource):
isLeaf = True
def render_GET(self, request):
request.setHeader("Content-Type", "application/x-x509-ca-cert")
cert = open(CERT_FILE, 'rb').read()
request.write(cert)
request.finish()
return server.NOT_DONE_YET
log.startLogging(sys.stdout)
context = make_ssl_context()
cert_site = server.Site(CertPage())
site = server.Site(HelloWorldPage())
reactor.listenTCP(8080, cert_site)
reactor.listenSSL(8081, site, contextFactory = context)
reactor.run()
How to generate a self-signed certificate using pyOpenSSL
February 12, 2010
If you’ve got an embedded web server (I’m currently writing one that will be used to configure an application), and you don’t want to pass things in the clear, you’ll need to configure your web sever to use HTTPS. But for an embedded application, that can be tricky – https expects the hostname to be signed in the certificate, but you probably don’t know it until after your app is installed.
Here’s how you can create a self-signed certificate programatically in python. You could just run this on application start-up. Not that first you’ll need to install pyOpenSSL (if you have easy_install set up, it’s as easy as “easy_install pyopenssl”):
from OpenSSL import crypto, SSL
from socket import gethostname
from pprint import pprint
from time import gmtime, mktime
from os.path import exists, join
CERT_FILE = "myapp.crt"
KEY_FILE = "myapp.key"
def create_self_signed_cert(cert_dir):
"""
If datacard.crt and datacard.key don't exist in cert_dir, create a new
self-signed cert and keypair and write them into that directory.
"""
if not exists(join(cert_dir, CERT_FILE)) \
or not exists(join(cert_dir, KEY_FILE)):
# create a key pair
k = crypto.PKey()
k.generate_key(crypto.TYPE_RSA, 1024)
# create a self-signed cert
cert = crypto.X509()
cert.get_subject().C = "US"
cert.get_subject().ST = "Minnesota"
cert.get_subject().L = "Minnetonka"
cert.get_subject().O = "my company"
cert.get_subject().OU = "my organization"
cert.get_subject().CN = gethostname()
cert.set_serial_number(1000)
cert.gmtime_adj_notBefore(0)
cert.gmtime_adj_notAfter(10*365*24*60*60)
cert.set_issuer(cert.get_subject())
cert.set_pubkey(k)
cert.sign(k, 'sha1')
open(join(cert_dir, CERT_FILE), "wt").write(
crypto.dump_certificate(crypto.FILETYPE_PEM, cert))
open(join(cert_dir, KEY_FILE), "wt").write(
crypto.dump_privatekey(crypto.FILETYPE_PEM, k))
A follow-up on the last post
January 15, 2010
I’ve done very little non-hobbyist Unix programming. I’ve been writing code for various Microsoft platforms professionally for over 20 years now. I have a far better understanding of the Unix security model.
How to test if a user is an adminstrator in Python
January 15, 2010
Note that you can’t just test for membership in the “administrators” group, or your code will fail if you run it in a non-english-speaking country (where “administrators” may be “Administrateurs”).
import ctypes
import ctypes.wintypes
def current_user_is_admin():
return user_token_is_admin(0)
def user_is_admin(username, password, domain=None):
"""note that username, password, and domain should all be unicode"""
LOGON32_LOGON_NETWORK = 3
LOGON32_PROVIDER_DEFAULT = 0
token = ctypes.wintypes.HANDLE()
if ctypes.windll.advapi32.LogonUserW(username, domain, password,
LOGON32_LOGON_NETWORK, LOGON32_PROVIDER_DEFAULT, ctypes.byref(token)) == 0:
raise Exception("user logon failed")
try:
return user_token_is_admin(token)
finally:
ctypes.windll.kernel32.CloseHandle(token)
def user_token_is_admin(user_token):
"""
using the win32 api, determine if the user with token user_token has administrator rights
See MSDN entry here: http://msdn.microsoft.com/en-us/library/aa376389(VS.85).aspx
"""
class SID_IDENTIFIER_AUTHORITY(ctypes.Structure):
_fields_ = [
("byte0", ctypes.c_byte),
("byte1", ctypes.c_byte),
("byte2", ctypes.c_byte),
("byte3", ctypes.c_byte),
("byte4", ctypes.c_byte),
("byte5", ctypes.c_byte),
]
nt_authority = SID_IDENTIFIER_AUTHORITY()
nt_authority.byte5 = 5
SECURITY_BUILTIN_DOMAIN_RID = 0x20
DOMAIN_ALIAS_RID_ADMINS = 0x220
administrators_group = ctypes.c_void_p()
if ctypes.windll.advapi32.AllocateAndInitializeSid(ctypes.byref(nt_authority), 2,
SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_ADMINS,
0, 0, 0, 0, 0, 0, ctypes.byref(administrators_group)) == 0:
raise Exception("AllocateAndInitializeSid failed")
try:
is_admin = ctypes.wintypes.BOOL()
if ctypes.windll.advapi32.CheckTokenMembership(
user_token, administrators_group, ctypes.byref(is_admin)) == 0:
raise Exception("CheckTokenMembership failed")
return is_admin.value != 0
finally:
ctypes.windll.advapi32.FreeSid(administrators_group)
Moderately funny
December 15, 2009
But this one line is worth the visit:
SOA is not complex. You are just dumb.
This is not an uncommon attitude, and I have no patience for it. While looking up some information on SCons, I encountered a blog comment that more-or-less said “There’s no need for SCons. make + autoconf isn’t complicated, you’re just dumb.” Okaaaaay.
Asserts vs Defects
November 23, 2009
This comes as no surprise to me – more assert()s means fewer defects.
I really dislike XML
November 16, 2009
Not technically Microsoft-hate, but since they’re such rabid XML-philes it counts. There are of course many reasons why XML is awful, but today’s example is the .exe.config file format that MS loves so much. Even programmers will mess up when editing one of those files, just imagine what will happen when your service people need to make a change. Do they even have a keyboard they’re familiar with? How do they figure out the syntax error they made in a huge mess of semi-structured ‘<’s and ‘>’s? When you’re trying to figure out what they did *over the phone* (no network connection on the demo floor, of course) you’ll learn to appreciate the .properties format real quick.
How to search for files that were modified today in Windows.
October 26, 2009
Windows has a “find” command, but it’s nothing like the Unix command “find” and is pretty useless. DIR can do recursive searches (using /s/b options), and is pretty useful, but there’s no way to get it to search based on dates – just file names.
But what if you want to know, for example, which log files have been modified today? Turns out, XCOPY can do this. It can copy files based on modification date, and the /L option tells it to just print the names of the files it would copy, but not actually copy them. Here’s the command to find all .log files on the C: drive that were modified on or after October 26, 2009:
xcopy /s /d:10-26-2009 /i /l /y c:\*.log \temp
Update:
Of course, you don’t want to manually specify the date every time. You could use the %DATE% cmd variable, but the output is wrong:
C:\temp>echo %DATE%
Wed 10/28/2009
The solution is to pick apart the string returns by %DATE% and munge it back together in the desired format:
C:\temp>echo %DATE:~4,2%-%DATE:~7,2%-%DATE:~10,4%
10-28-2009
So, the command to find all tomcat logs that have changed today becomes:
xcopy /s /d:%DATE:~4,2%-%DATE:~7,2%-%DATE:~10,4% /i /l /y c:\tomcat5.5\*.log \temp
How to find which jar contains the class you need.
October 26, 2009
One of the great things about Java tool chain is that it accepts the Unix principle of “small sharp tools”. So, instead of some crazy proprietary binary format, java libraries are either .class files in a directory tree that mirrors their package hierarchy or they’re a .zip file, again with the paths of the .class files it contains mirroring their package hierarchy (that’s all a .jar file is).
This means that you don’t need to use specialized tools to do some simple browsing. For example, I’ve recently needed to construct an SDK to work with a third party web-based application that we’re using at my day job. The vendor doesn’t have a productized SDK that I can use, but I do have a working server, so in theory I have all the .jar files that I need *somewhere*. All I needed to do is figure out where.
Since a .jar file is just a Zipped archive of class files, if I can get the list of each .class file in all the .jars on the system, I should be able to figure out which one holds the class I needed, and just copy that to my development machine.
The command to get the list of .class files in a .jar file is this:
jar.exe -tvf jar file name
To only list those files that match the name of your class, do this. Note that you can use the entire path, like com.mycompanyname.MyClassName. Jar outputs ‘/’s instead ‘.’s to separate package segments, since as far as jar is concerned, these are file paths, not java package names, but since the ‘.’ is a findstr pattern that means ‘match any character’, it works just fine):
jar.exe -tvf jar file name | findstr class name
To recursively perform a command on all jar files in a directory tree, you use the FOR command, like this:
for /r tree root %f in (*.jar) do my command to %f
Combined, they look like this:
for /r tree root %f in (*.jar) do jar.exe -tvf %f | findstr class name
Unfortunately, this just outputs the names of the class files that match the class name argument. What we really want is the names of the .jar files. It’s in %f, so all we need to do is ECHO %f. But, we only want to do that if FINDSTR found a match. For that, we need the && operator – cmd1 && cmd2 executes cmd1, and if cmd1 sets ERRORLEVEL to 0, executes cmd2. Since FINDSTR sets ERRORLEVEL to 0 on match and 1 on no match, this will work perfectly.
Here’s the final result:
for /r tree root %f in (*.jar) do jar.exe -tvf %f | findstr class name && echo %f
Or, if we just want to see the .jar names, and not the names of the .class files in that .jar that matched:
for /r tree root %f in (*.jar) do jar.exe -tvf %f | findstr class name > NUL && echo %f