Introducing Authen::CAS::External

I have uploaded a new module to the CPAN: Authen::CAS::External. Yes, the module was actually uploaded a while ago, but I have not gotten around to writing about it until now. This module performs authentication against a CAS server on behalf of a user. Currently the module only supports simple authentication using a username and password or using an already authenticated ticket granting cookie.

The main purpose of this module is not really for web scrapers, as they can easily just fill in the form with a username and password and proceed onward, but for more specific uses of the CAS service by third party clients. A use case I am using this module for is to authenticate with the CAS server with a username and password and get the ticket for a specific service, which I can then use to gain access to the service with that username and password on an entirely separate browsing session.

There is one more scenario I use this module for, and that is to authenticate against the CAS server, and then hand over the ticket granting cookie to another process which can then log into services using that CAS server without ever knowing the username and password.

#!/usr/bin/env perl
 
use 5.008001;
use strict;
use warnings;
 
use Authen::CAS::External 0.01;
use URI;
 
my $authen_server = Authen::CAS::External->new(
    cas_url  => URI->new('https://cas-server.example.net'),
    username => 'testaccount',
    password => 'testpassword',
);
 
my $response = $authen_server->authenticate(
    service => 'https://some-service.example.net/',
);
 
if (!$response->is_success) {
    print {*STDERR} "Invalid credentials supplied\n";
    exit 1;
}
 
print $response->ticket_granting_cookie, "\n";
 
exit 0;

Nagios::Plugin::OverHTTP gets timeout

In versions of Nagios::Plugin::OverHTTP previous to 0.06 the only way to set a timeout on the plugin was to initiate your own LWP::UserAgent and set the timeout on it and pass that to Nagios::Plugin::OverHTTP like:

use LWP::UserAgent;
use Nagios::Plugin::OverHTTP;
 
my $ua = LWP::UserAgent->new(timeout => 20);
my $plugin = Nagios::Plugin::OverHTTP->new(useragent => $ua);

So now you can skip the entire custom user agent step unless you actually want a custom user agent:

use Nagios::Plugin::OverHTTP 0.06;
 
my $plugin = Nagios::Plugin::OverHTTP->new(timeout => 20);

In addition verson 0.07 changes the check_over_http script so that the timeout defaults to 10 seconds, which is reasonable with Nagios plugins.

New check_over_http features

Yesterday I finished up some more features to Plugin::Nagios::OverHTTP. Before the only parameter that could be passed was url. Now this parameter can still be passed, but you may also pass other individual parameters, including hostname, path, and ssl. This helps improve the check_over_http utility which would be used in the Nagios checking. Typically the command definition would have been something like the following:

define command{
        command_name check_over_http
        command_line check_over_http --url=$ARG1$ $ARG2$
        }

This means the following would need to be in a service definition:

define service{
        use                            noncritical-service

        host_name                      server1
        service_description            Connection to MySQL
        notes                          Checks if the server can connect to remote MySQL
        check_command                  check_over_http!http://server1/nagios/check_remote_mysql
        }

As you can see, the check command duplicates the hostname, which is not the way of Nagios plugins. Now With version 0.04 and up, we can have the following definitions:

define command{
        command_name check_over_http
        command_line check_over_http --hostname=$HOSTADDRESS$ --path=$ARG1$ $ARG2$
        }
define service{
        use                            noncritical-service

        host_name                      server1
        service_description            Connection to MySQL
        notes                          Checks if the server can connect to remote MySQL
        check_command                  check_over_http!/nagios/check_remote_mysql
        }

Installing Windows Vista/7 from a USB flash drive

This post is a nice how to about making a bootable USB flash drive to install Windows Vista or Windows 7 from. Unless you are using a super fast flash drive, it won’t be much faster than a DVD, but the plus of this method is being able to not use a DVD and to be able to swap out different WIM images for deployment. This guide details the steps using a Windows Vista machine, but should be the same for a Windows 7 machine.

  1. Insert the USB flash drive you want to use into a USB port on your computer. The standard Windows Vista/7 DVD is about 2.4 GB, so you will want to be sure your flash drive is at least that big. It may need to be bigger depending on if you are using a custom WIM.
  2. Open Command Prompt as administrator
    Right-click on Command Prompt and select Run as administrator
  3. At the command prompt, you will want to start the diskpart utility by typing diskpart and pressing Enter.
    Type diskpart and press Enter
  4. Type list disk and press Enter and diskpart will list all the disks that are connected to your computer. You can identify which one is your target flash drive based on the size. For this I am using a 4 GB flash drive, so Disk 1 is my target disk.
    Typing list disk will display a list of the connected disks
  5. Now type select disk # and press Enter, replacing # with the disk number you determined from the step above.
    select disk 1
  6. Now it is time to wipe everything from the flash drive. Type the command clean and press Enter.
    Type clean to clean the disk
  7. Now type in the command create partition primary and press Enter. This will create a new primary partition on the drive occupying the entire disk. Once this is done, type select partition 1 to select the partition that was just created.
    Create and select a new primary partition
  8. To make this partition bootable, it needs to be marked as an active partition. To do this, type the command active and press Enter.
    Mark the partition as active
  9. Now it is time to format the partition. For this, the format will be FAT32. To conserve time, the quick formatting option is desired. Type the command format fs=fat32 quick and press Enter. Because of the quick option, the formatting should take less than 30 seconds.
    Format the partition to FAT32
  10. After the formatting is complete, the drive should automatically become present in Computer. If not, you may type the command assign and press Enter which will make the drive available in Computer. You may now exit from diskpart using the exit command.
    Exit diskpart
  11. Now the drive is ready for the installer files to be copied to it. You may copy-and-paste from a DVD in your DVD drive. The following demonstrates how to extract the files from an ISO file to the drive using the 7-Zip program. Just right-click on the ISO file and select 7-Zip and Extract files…
    Extracting files from ISO using 7-Zip
  12. In Extract to, choose the flash drive. In my case, the flash drive is assigned the letter G, so I am extracting into G:\. Click OK to begin the extraction. Depending on how fast your flash drive is, this may take some time.
    Choose where to extract the files from the ISO 
  13. After the extraction, the flash drive is ready to be booted to and can install Windows onto the destination computer.

First Perl Module on CPAN

Yesterday I published my first full module to CPAN: Nagios::Plugin::OverHTTP. The module is based on Moose and includes the Nagios plugin in the distribution in bin/check_over_http. I will be improving this module, but wanted to push it out to CPAN as soon as it was at least usable. The module is avaiable in my Github account under perl5-nagios-plugin-overhttp for forking and public versioning.

Beginning Windows PowerShell

Windows PowerShell icon Once again, things change in the software world. This time it is Windows PowerShell. PowerShell was been around for quite a while now, but I am settling down to start using it regularly. So far it seems to be pretty hit-and-miss with finding documentation online through search engines, but then again I am not too sure what I should be searching just yet.

For managing computers, I have many batch scripts, which I would like to fully replace with PowerShell scripts. With just a little bit of work, I can gladly say that Microsoft has a very well-designed shell environment on their hands here.

Never Trust the Client

Please, never trust the client. I’m not sure how much this can be stressed. After writing unsupported interfaces for various programs (most commercial) I find that this basic rule is not always followed. Gone are the days where people submit forms and then the server checks the inputs and will return one or more error messages for bad input. Now much of the error checking is done in the browser to make it more convenient for the end-user, as they won’t have to wait for a round-trip of their data to realize that they entered only four numbers for a U.S. zip code.

The problem is at one time all checking was done server-side. Then for end-user convenience, most or all of the checks were duplicated on the client-side. Now I am seeing developers “forget” to check things on the server-side. In the days of increased attacks on web sites, this becomes more critical. The client can never be trusted. Once the JavaScript is loaded in the end-user’s browser, it can be manipulated and checks disabled, allowing them to submit bad data. They may even just submit the data to your server by just constructing the HTTP request themselves.

Just today I was working on creating an unsupported interface to a popular commercial software that many companies use. While reverse-engineering different parts or their interface’s code, I found that they must have been lazy, because they send an “API” command that looks suspiciously exactly like PHP. I put a syntax error in it and it complained about a syntax error in an eval() statement. An eval() statement?! Yes, I can execute anything I want on the server, making any kind of access control obsolete, as I have direct access to the running PHP instance, the database server, and the file system.

So, please,

die unless $i_am_a_number =~ m{\A\d+\z}mx;

our $AUTHORITY

So what is the business with the following global variable I keep seeing in CPAN modules these days?

our $AUTHORITY;

So I searched a bit to figure it out, and found it made its way from Perl 6. A description of its use in Perl 6 can be found in Synopsis 11: Modules. Essentially Perl 6 saw that there would be no reason why there can’t be more than one module named Foo::Bar. You can already designate a minimum version required of a module, and you still can in Perl 6, but they saw that Foo::Bar is just a short name for the module. Its full name includes more parts, including the authority. So to load up the Foo::Bar I wrote in CPAN (note: I have no such module), you would say:

use Foo::Bar:auth<cpan:DOUGDUDE>;

When in the Foo::Bar module I specify:

our $AUTHORITY = 'cpan:DOUGDUDE';

File::OPC

From my earlier post, after talking in #Perl, I have changed the name of the module from Archive::OPC to File::OPC. It is still not on CPAN, as I won’t release it until it can at least read Open Packaging Convention files. The module is being written using Moose.

TortoiseSVN & PuTTY Internal Error

Recently I installed TortoiseSVN on a Windows Vista machine (though from reading different sources on the Internet, it applies to all platforms TortoiseSVN runs on, like Windows XP) and I was presented with the following error message when trying to connect to a repository over SSH (that is, svn+ssh):

PuTTY Internal Error - Invalid Port Number

I was looking around the Internet trying to find the solution, and after a bit stumbled upon the answer on some random forum. The error appears to be in the way in which TortoiseSVN calls PuTTY. The solution is to open the settings for TortoiseSVN and then go to the Network pane and under the SSH section, make sure the SSH client box is empty and does not have the path to PuTTY.

TortoiseSVN Settings

If you were wondering this applies to PuTTY 0.60 and TortoiseSVN 1.5.5 build 14361.