Freedom of Information, Request #2 – DETINI on BT 100% broadband deal

Tony writes over on his blog about several of his FOI requests.

It seems he is having a better time than myself with DETI.

Exactly 20 (business) days ago I emailed DETI NI to request information pertaining to the contract they awared BT to provide 100% Broadband coverage for Northern Ireland before the end of 2005.

That date is getting close and so far it isn’t there. So I wondered what penalties were in the contract if BT failed to achieve the target date.  This information is also very much in the public interest, so I intended to publish it here also.

So the 20 days have come and gone and DETI NI are a no show.  Thus I have a right to complain directly to the Information Commissioner – "failure to respond to your request within 20 working days (or failure to explain why longer than 20 working days is needed)".  But they also make a point of saying you needed to supply a copy of the complaint to the body also, so to ensure DETI NI have a chance to rectify the situation I am complaining to them first.  I’m not sure how long I’ll leave the complaint with them but I expect they should come back to me pretty quickly.  This time, instead of emailing, I used their online form so they have no excuses.

I have enclosed a copy of the original request below, and the complaint below that.

To: information@detini.gov.uk
Subject: Freedom of Information Act: Request for details of BT 100% Broadband contract
Date: Thu, 15 Sep 2005 14:05:17 +0100

Dear sirs,

In March 2004, DETI NI awarded a contract to BT to deliver 100% broadband
coverage to Northern Ireland before the end of 2005

"By the end of 2005 every household and every business in Northern Ireland,
no matter how remote, will have access to broadband at the same price."
– IO Minister for Enterprise, Trade and Investment, Ian Pearson MP, March 2004
announcing the deal.

This request under the FoI is for the following information:

1. Copy of the contract awarded to BT and any subcontractors
2. Details of when DETI considers the contract completed.
3. Penalties and remedies for failure to meet the contracted deadlines.

I believe that the nature of this contract and its vital importance to the
NI economy would mean that this information passes the "Public Interest
Test" and you should not be able to claim any exemptions.

I can be reached via:
Address:        Paul Gregg
                      xxxxxxxxxxxxxxx  Address details removed :)

Email:          xxxxxxxxxxxxxx

Telephone:      xxx xxxx xxxx

Thank you for your attention to this matter.

Yours faithfully,

Paul Gregg

PS. Your document explaining how to make a FoI request does not
include your email address.  I trust you will correct this omission.
http://www.detini.gov.uk/cgi-bin/moreutil?utilid=415


Pursuant to the Publication Scheme and your duty onder the Freedom of Information Act I am writing to complain about your failure to acknowledge or respond to my FOI request of Thursday 15 September 2005, 20 business days ago.

Mail server logs confirmed that your system accepted the email which was sent to
information@detini.gov.uk.

Yours faithfully,

Paul Gregg
(copy of original request was sent with the complaint

Compiling PHP, OCI8 on Sparc64 Solaris 10 with Oracle10g

This problem beat me about the head for most of yesterday until I worked out that PHP 5.0.5 doesn’t actually know about Oracle 10.    8 and 9, sure thing – otherwise it decides it is an older version (very silly).

The other problem is that when PHP tries to link to the oracle client libraries, by default it attempts to link against the 64 bit libraries – which with PHP being a 32bit app just isn’t going to fly.

So here I will attempt to guide you in all that is good with PHP and Oracle 10.

The first thing to do is ensure you have a working Solaris 10 install with Oracle 10g already
installed.   As this was to be an actual server machine I installed the full database server including client libraries (which happens by default when you install server).  However the purpose of this is not to help you install Oracle – there are plenty of guides out there for that.  This is to help you get PHP compiled in this environment – there are no guides for that.

So lets unpack the PHP source:
#->tar xf php-5.0.5.tar
#->cd php-5.0.5
php-5.0.5-#->

Now, If you run a straight ./configure –with-oci8 it will most likely fail being unable to find the oracle install:
checking Oracle version… configure: error: Oracle (OCI8) required libraries not found

We need to tell it where to find the oracle libraries.
./configure –with-oci8=/u01/app/oracle/product/10.2.0/Db_1
(assuming this is where your default database was installed to)

This will enable configure to complete.

Next, naturally, we try to make php – all should go well right up until the final link:
php-5.0.5-#->make
… [snip] …
ld: fatal: file /u01/app/oracle/product/10.2.0/Db_1/lib/libclntsh.so: wrong ELF class: ELFCLASS64
ld: fatal: File processing errors. No output written to sapi/cgi/php
collect2: ld returned 1 exit status
make: *** [sapi/cgi/php] Error 1

This fails because PHP has decided to link against lib/libclntsh.so when it should have linked against lib32/libclntsh.so

No amount of adding –includedir= and –libdir= on the configure command will result in make doing the right thing and linking against the lib32 version.

The solution? We need to edit the configure script to tell it that lib isn’t the be-all and end-all of oracle libraries.  This is a pain, I know, but hopefully the PHP people will fix this for 5.0.6 and above.

At line 64660 in configure you will see the line:
  elif test -f $OCI8_DIR/lib/libclntsh.$SHLIB_SUFFIX_NAME.10.1; then

Change /lib/ to /lib32/

And at line 69134 you’ll notice that it is missing any reference to Oracle 10.1, so we need to add it – add the following two lines just before the 9.0 line:
  elif test -f $ORACLE_DIR/lib32/libclntsh.$SHLIB_SUFFIX_NAME.10.1; then
    ORACLE_VERSION=10.1

At line 64977 change:
  if test -z "$OCI8_DIR/lib" || echo "$OCI8_DIR/lib" | grep ‘^/’ >/dev/null ; then
    ai_p=$OCI8_DIR/lib
to:
  if test -z "$OCI8_DIR/lib32" || echo "$OCI8_DIR/lib32" | grep ‘^/’ >/dev/null ; then
    ai_p=$OCI8_DIR/lib32

Line 64368: add
  OCI8_SHARED_LIBADD="-L$OCI8_DIR/lib32"
  LIBS="$LIBS -L$OCI8_DIR/lib32"

Now make clean;
cd to your database and rename the lib directory to lib.unused temporarily so that PHP cannot link against it and leave the lib32 one as is.

Switch back to php dir. Run your configure command, make (which should now complete) and make install.

Go back and rename the lib.unused back to lib as other things will need this to exist.

Finally, make sure you add the lib32 path to your LD_LIBRARY_PATH variable before starting apache/php

LD_LIBRARY_PATH="$LD_LIBRARY_PATH:/u01/app/oracle/product/10.2.0/Db_1/lib32"

Your PHP should now be working fine.

Files to help: My "configure" command:
‘./configure’
‘–prefix=/usr/local/apache2’
‘–includedir=/space/app/oracle/product/10.2.0/Db_1/rdbms/public’
‘–oldincludedir=/space/app/oracle/product/10.2.0/Db_1/rdbms/public’
‘–libdir=/space/app/oracle/product/10.2.0/Db_1/lib32’
‘–with-apxs2=/usr/local/apache2/bin/apxs’
‘–with-oci8=/u01/app/oracle/product/10.2.0/Db_1’

Diff of the configure script to the regular one supplied with PHP 5.0.5
#->diff php-5.0.5/configure php-5.0.5-working/configure                           6:39AM
64367a64368,64369
>   OCI8_SHARED_LIBADD="-L$OCI8_DIR/lib32"
>   LIBS="$LIBS -L$OCI8_DIR/lib32"
64660c64662
<   elif test -f $OCI8_DIR/lib/libclntsh.$SHLIB_SUFFIX_NAME.10.1; then

>   elif test -f $OCI8_DIR/lib32/libclntsh.$SHLIB_SUFFIX_NAME.10.1; then
64977,64978c64979,64980
<   if test -z "$OCI8_DIR/lib" || echo "$OCI8_DIR/lib" | grep ‘^/’ >/dev/null ; then
<     ai_p=$OCI8_DIR/lib

>   if test -z "$OCI8_DIR/lib32" || echo "$OCI8_DIR/lib32" | grep ‘^/’ >/dev/null ; then
>     ai_p=$OCI8_DIR/lib32
69133a69136,69137
>   elif test -f $ORACLE_DIR/lib32/libclntsh.$SHLIB_SUFFIX_NAME.10.1; then
>     ORACLE_VERSION=10.1

Note to PHP developers if they read this – this patch is not one that can be dropped into the regular build – it will only help people who have difficulty installing PHP with OCI8/Oracle10 on Solaris10.

I hope this proves useful to others – it took me >24 hours work to get to this point.

Buy the Whitehouse, get an SQL injection attack

The Internet casino and poker house GoldenPalace.com bought up the only known deed for The White House as reported by The Inquirer.

Except that the link that the inq uses to get to the page telling the story at casinocitytimes.com revealed a little more information than they should have.   Because the URL on the inq was mistyped – they tried to make two links but only made one broken one.

When I clicked on the link: http://www.casinocitytimes.com/news/article.cfm?contentID=153470%5D %20and%20here%20[http://realtytimes.com/rtcpages/20050831_titleinsurance.htm I received an error page that was obviously the result of an unchecked contentID being passed right from the url into the SQL.

This is a classic case of unchecked user supplied data being trusted which leads to a compromise in security and some very red faces when some naughty people get hold of it.

I hope they fix it soon.

PHP: HTTP Authentication via PHP

When combining sessions with HTTP Auth in order to maintain state. The difficulty surrounding HTTP Auth is that even after you "logout", the browser will continue to send the correct username and password with each request. Thus immediately logging you back in again – unless you use the states to keep track carefully.

In this example we will use two session variables to maintain state and we tell the page that we want to login our logout via an argument in the query string, e.g. ?login ?logout

The two state variables are:

    * LOGGEDIN – Very simple state – either you are logged in or not
    * LOGGEDOUT – Will be TRUE if we have logged out. It’s primary purpose is to scupper the browser provided password and prevent the authentication routines from running. It gets reset to FALSE when we want to login

Additional benefits to this method are that we only need to authenticate upon login once. Normal code implemented HTTP Auth routines authenticate with every page request

Source code: Example page protected with PHP HTTP Auth

Source code: PHP HTTP Auth include file

In order to use this to protect any page you need to copy the auth.inc.php file to your server and then simply include or require it in any page.
You may wish to set the variable $HTTP_AUTH_REALM to a string before including this as this will change the Basic Realm information in the auth dialog box to a string of your choice.

You should also look at the checkpw() function and replace that with something that will check your user credentials correctly. Input is username, password and it should return TRUE or FALSE if the credentials supplied are OK or not.

Finally, on any page to effect a change of state from logged in to logged out or vice-versa, you simply have to make a link to a page with "login" or "logout" in the url’s Query String (that is the bit after the ?), e.g. page.php?login

A working example is provided over in my projects section, the default username is "paul" and password is "gregg"

I hope this code serves as useful learning material. Good luck.

Freedom of Information, Request #1, The reply.

It was remiss of me not to follow up on my earlier FOI post (thanks Tony for the prompt).  Rather than just post the reply as a comment to that post (it’ll never be seen), I will post it here.

Basically they decided to withhold the information as it pertains to current policy discussion.

Here is a GIF of the response (resized):

Full size version can be found here

Shame really.

Belfast Zoo: Escaped Ringtailed Lemur

This didn’t hit the press – but I guess an escaped Lemur isn’t quite as scary as an escaped Lion.

I took the kids to the Zoo this past Bank Holiday Monday – pretty normal trip to the zoo as zoo trips go.  However, nearing the end I came across this escaped Ringtailed Lemur sitting in a tree outside a monkey enclosure.

I was able to walk right up to him and get my camera to within about 1 foot of him and take some great shots.

More pictures (and higher quality) are available over on my Gallery site.

String Case Conversion in PHP

Occasionally I read through some comments on the PHP Manual, sometimes to get ideas on different methods of doing things, other times just to try to keep current with some of the vast array of functions available.

Sometimes, I see things that really scare me – code that is written and published with the best will in the world from the author – but yet displays a lack of a deeper understanding of how to solve a problem.  One such case was the invert_case() and rand_case() functions which basically looped through each character in a string doing whatever it had to do to each character as it went.  Highly inefficient.

Remember, the only difference in ASCII between an uppercase letter and a lowercase letter is a single bit that is 0 for uppercase and 1 for lowercase.

This brief tutorial is based on code available at:
http://www.pgregg.com/projects/php/code/str_case.phps
and you can see example output at:
http://www.pgregg.com/projects/php/code/str_case.php

Surely it would be possible to write some code that would simply flip this bit in each character to the value you want:
– AND with 0 to force uppercase
– OR with 1 to force lowercase
– XOR with 1 to invert the case
– randomly set it to 1 or 0 to set random case.

There are two methods to achieving this, the first makes a simple character mask and performs a bitwise operation on the string as a whole to change it as required.  This method is designed to help teach how this works.  The second method uses the power of the PCRE engine by using a regex to calculate the changes and apply them in one simple step.

Both solutions are, I believe, elegant and are presented here for you.

Solution #1:

Code:

// Code that will invert the case of every character in $input
    // The solution is to flip the value of 3rd bit in each character
    // if the character is a letter. This is done with XOR against a space (hex 32)
    $stringmask = preg_replace("/[^a-z]/i", chr(0), $input); // replace nonstrings with NULL
    $stringmask = preg_replace("/[a-z]/i", ' ', $stringmask); // replace strings with space
    return $input ^ $stringmask;


The method here is to generate a string mask, in two stages, that will act as a bitmask to XOR the 3rd bit of every letter in the string.  Stage 1 is to replace all non-letters will a NULL byte (all zeros) and Stage 2 is to replace all letters with a space (ASCII 32) which just happens to be a byte with just the 3rd bit set to 1 i.e. 00100000
All we have to do then is XOR our input with the string mask and magically the case of all letters in the entire string are flipped.

Solution #2:

 

Code:

return preg_replace('/[a-z]+/ie', ''$0' ^ str_pad('', strlen('$0'), ' ')', $input);


Much more compact and works by using a regex looking for letters and using the i (case insensitive) modifier and most importantly the e (evaluate) modifier so we can replace by executing php code.  In this case, we look for batches of letters and replace them with itself XORed with a string of spaces (of the same length).

Similar principles apply to the random case example, but we complicate this slightly by adding and invert mask (to the solution 1 method). This invert mask is created by taking a random amount of spaces (between 0 and the size of the input string). We then pad this out to the size of the original string with NULL bytes and finally randomise the order with str_shuffle().  We then bitwise AND the stringmask and the invertmask so we create a new mask where randomly letters in the mask have spaces or NULLs.  We then XOR this to the original string as before and before you know it you have a randomly capitalised string.
The Solution 2 version requires you to remove the + so that we only match a single letter at a time (or else our randomly chosen case would apply to words at a time), and we use a termary to randomly decide on using a space or a NULL:

 

Code:

return preg_replace('/[a-z]/ie', '(rand(0,1) ? '$0' ^ ' ' : '$0')', $input);


I hope this has been a worthwhile read and I would certainly welcome feedback on this article.

Damn forum / web log / blog comment spammers.

It got so bad over the past few days that I was regularly deleting 5+ posts a day advertising the latest gamling establishment or where to get the cheapest erectile medications. So as with all good reasons for doing some programming – being pissed off – I wrote some captcha code that will display an image of some text that you have to enter to authorise the post.

The image/captcha is not there if you create an account, so please do so.

Oh, and for those interested, I coded it from scratch without outside 3rd party code and merged it into my existing 3rd party punbb forum code.  Total time, approx 1 hour.

Free Credit Card

Those of you who regularly read this tome (thanks mum!) may be aware that I recently applied for an Alliance & Leicester Premier Plus account with Credit Card.  Story is over here.

As I noted, when I read the Terms & Conditions (that they send out to you to get a real signature since I applied online) I decided I did not like the Credit Card terms and scrawled a large C-A-N-C-E-L-L-E-D across that particular "agreement" and did not sign it.

So imagine my surprise at what arrived in this morning’s post:

How is it possible for a bank to hand out a credit card in this way?

Apparently I now have 5 days to cancel this "agreement" that I never made.  I guess I better at least try to cancel ‘by the book’ or watch my credit rating go to hell.

All content © Paul Gregg, 1994 - 2024
This site http://pgregg.com has been online since 5th October 2000
Previous websites live at various URLs since 1994