DKIM signing in perl

MT Hosting
#[email protected]
#Simple DKIM
#V0.1

use Mail::DKIM::Signer;
use Email::Simple;

@ARGV == 1 or die "Missing File Name";

$domain = "mysecureservice.com";
$key = "C:\\Ahsay\\CustomScripts\\$domain.priv";
$dkimsel = "dkim";
$dksel = "dk";
my $dkim = Mail::DKIM::Signer->new(
Algorithm => "rsa-sha1",
Method => "relaxed", 
Domain => $domain, 
Selector => $dkimsel, 
KeyFile => $key);

open(mail,"< $ARGV[0]");
$emailm = "";

while ()
{
chomp;
s/\015$//;
$dkim->PRINT("$_\015\012");
$emailm = "$emailm"."$_\n";
}
$dkim->CLOSE;
close mail;

my $email = Email::Simple->new($emailm);
$dkimsig = $dkim->signature->as_string();
$dkimsig =~ s/DKIM-Signature: //;

$email->header_set("DKIM-Signature", $dkimsig);


open (mail, "> $ARGV[0]");
$emailmsg = $email->as_string;
#$emailmsg =~ s/\015$//;
print mail $emailmsg;
close mail;

Cross-Platform Message Box

I needed a cross-platform message box for Windows and Mac. I tried wxperl because its native on the mac but their is a bug with their MessageBox code on the mac.

This is pretty simple code, but uses each O/S’s native message box API to display a dialog. If you have Yes/No buttons and click yes it will perform the item in action. Which for us opens a webpage. You only need a standard perl installation for this code.


WHS Bliss

I just finished upgrading my DNS-323 NAS to a Acer H340 Windows Home Server NAS.

I am also running Ahsay Off-Site backup software on the unit to backup my Macintosh laptops and a couple of friends computer.

So far no complaints. The media streaming to the Xbox 360 is great also.

Poor Man’s TS Universal Print Driver

All the terminal services print drivers I found were too expensive for a 2 user TS environment that I was maintaining.

  • On the client download and install this open source pdf print driver for windows http://www.pdfforge.org/.
  • Setup the pdf printer to automatically print to the client printer and to auto save.
  • On the server install the open source pdf print driver and delete the printer it creates so now you have the drivers on the server.

From the client connect to the terminal server and print a test page, you should get a print pop up asking to confirm the print settings.

The reason this works is that the pdfforge will send the PS document to the client computer to be processed. The best benefit is that its all free.

Google Voice Call Widget POST commands

Google made their Google Voice call widget flash only. There are alot of instances where you want to be able initiate a call from non-flash.

I hope this helps with integration to other projects.

The POST URLs are:
https://clients4.google.com/voice/embed/webButtonConnect
https://clients4.google.com/voice/embed/cancelWebButtonCall

webButtonConnect expects the following parameters.
showCallerNumber (Google’s Widget send the number 1)
callerNumber (The 10 digit number with no spaces or dashes)
buttonId (the id value from your flash call widget)
name (The name of the caller)

cancelWebButtonCall expects the following parameters.
buttonId (the id value from your flash call widget)
callerNumber (the number of the call you want to cancel)

Post Returns:
ok=false (Error)
ok=true (Call Placed)

Here is a quick and dirty HTML form to make a call.

Enabling DHCP Option 119 on 2003 Server

DHCP option 119 is the option to send out DHCP domain search list to clients, it is documented in RFC 3397.

It is only supported in Macintosh, Windows XP and older does not support it and as far as I know neither does Vista. You must use GPO for Windows.

In your Windows DHCP server do the following

  1. Go to “Set Predefined Options”
  2. Click Add
  3. Name: Domain Search List
  4. Data Type : Byte, Check Array
  5. Code: 119

To create your byte array go to http://www.string-functions.com/string-hex.aspx and type in your domain. We will use apple.com as our example.

We are returned get back this: 6170706c652e636f6d

To enter them in to DNS we have to add 0x in front of each pair. Which gives us 0x61 0x70 0x70 0x6c 0x65 0x2e 0x63 0x6f 0x6d (A)

Add up all the groups which is 9 in our example and convert that to hex which is 0x9 (B).

Now, in Windows DHCP you have to enter value one at a time into DNS. When you enter your first value MS adds a 0x0 which you have to remove first.

Then add all the values from (A) first the (B) and you are all set.

Serv-U Helm3 Quota Interface

'Serv-u Account Management
ver="V2.0"
'servudiskq.vbs

'Server Settings
'Helm SQL/MSDE Server Location
HelmDB="vicky\helm"

'Serv-U Domain Instance, this is located in the registry
SUDomain=1

'ServuDaemon File Location
ServuDaemon="C:\Program Files\Serv-U\ServUDaemon.ini"

'Operations: True is for enabled, Fales is for disabled.
'This will enabled writing the quota to the serv-u registry
SetQuota=True
'This will enabled or disabled the account based on the user account status
SetStatus=True

WScript.Echo "Serv-u Helm Qouta " & ver

'Check if Serv-U ini Exists.
Set filesys = CreateObject("Scripting.FileSystemObject")
If NOT filesys.Fileexists(ServUDaemon) Then
 wscript.echo "ERROR... ServuDaemon.ini does not exist"
 Set filesys = nothing
 wscript.quit(5)
end if

'Check for Servu-Domain In Registry
Set objShell = WScript.CreateObject("WScript.Shell")
SUDomainChk=""
On Error Resume Next
SUDomainChk=objShell.RegRead("HKLM\SOFTWARE\Cat Soft\Serv-U\Domains\DomainList\" & SUDomain)
On Error Goto 0
If SUDomainChk = "" Then
 wscript.echo "ERROR... Serv-U Domain Not Found"
 Set objshell = nothing
 wscript.quit(5)
end if

Set rsOBJ = CreateObject ("ADODB.Recordset")
strConnect = "Driver={SQL Server}; Server=" & HelmDB & "; Database=helmdb;"

'Open Helm
WScript.Echo "Connecting to Helm Database..."
rsOBJ.Open "Select FTPAccount.FTPUserName, COALESCE(HostDomain.CurrentDiskspaceUsage,0) AS CurrentDiskSpaceUsage, SUM(Limit.LimitValue) AS DSTotal, Account.AccountStatus From FTPAccount,HostDomain,Package, Limit, Account WHERE FTPAccount.DomainId=HostDomain.DomainId  AND HostDomain.PackageId = Package.PackageId  AND Limit.LimitPropertyId=3 AND Package.AccountNumber = Account.AccountNumber AND(Package.PackageTypeId=Limit.ItemId OR HostDomain.PackageId=Limit.ItemId) GROUP BY FTPAccount.FTPUserName, HostDomain.CurrentDiskspaceUsage, Account.AccountStatus", strConnect
Do While Not rsOBJ.EOF
 CurrentDiskSpace_Bytes=rsObj("CurrentDiskspaceUsage")
 
 'Error Checking
 WScript.Echo "Found User " & rsObj("FTPUserName") & " Used/Total " & FormatNumber(cstr(rsObj("CurrentDiskspaceUsage"))/1024) & "MB/" & FormatNumber(cstr(rsObj("DSTotal"))) & "MB"
 
 If rsObj("AccountStatus") = 0 Then
  wscript.echo vbTab & "Account is Enabled"
  If SetStatus Then
   objShell.RegWrite "HKLM\SOFTWARE\Cat Soft\Serv-U\Domains\" & SUDomain & "\UserSettings\" & rsObj("FTPUserName") & "\Enable", "1", "REG_SZ"
   wscript.echo vbTab & "Writing Account Status"
  else
   wscript.echo vbTab & "Skipping Status..."
  end if
 else 
  wscript.echo vbTab & "Account is Disabled"
  If SetStatus then
   objShell.RegWrite "HKLM\SOFTWARE\Cat Soft\Serv-U\Domains\" & SUDomain & "\UserSettings\" & rsObj("FTPUserName") & "\Enable", "0", "REG_SZ"
   wscript.echo vbTab & "Writing Account Status, Account Disabled"
  else
   wscript.echo vbTab & "Skipping Status..."
  end if
 end if    

 If SetQuota Then
  'Update Serv-U Registry
  SUQuota="1|" & cstr(rsObj("DSTotal"))*1048576 & "|" & cstr(rsObj("CurrentDiskspaceUsage"))*1024
  objShell.RegWrite "HKLM\SOFTWARE\Cat Soft\Serv-U\Domains\" & SUDomain & "\UserSettings\" & rsObj("FTPUserName") & "\DiskQuota", SUQuota, "REG_SZ"
  WScript.Echo vbTab & "Writing Serv-u Qouta for " & rsObj("FTPUserName")
 else
  Wscript.Echo vbTab & "Skipping Quota..."
 end if
 rsOBJ.MoveNext
loop

objShell.run "cmd /c echo ReloadSettings=True >> """ & ServuDaemon & """",0
Wscript.Echo "Forcing Serv-U to reload settings."
Wscript.echo "Done."

'Close Us Down
rsOBJ.Close
set rsObj = nothing
Set filesys = nothing
set objshell = nothing
WScript.quit

This is an OLD vb script that I wrote for HELM3 to read the FTP users and their quota from a SQL database and writes the data to the registry to enforce the quota from the FTP Server.

This is a Email to Google Calendar Quickadd gateway.

You can email a special address and it will take the subject of the email and send it to googles quickadd feature. This is a simple way to add events to your google calendar via email.
http://www.google.com/calendar
http://framework.zend.com/download/gdata
http://www.google.com/support/calendar/bin/answer.py?hl=en&answer=36604

  • You need to have Zend’s Gdata framework installed.
  • The first code example you need to add your google calendar information
  • the 2nd peice of code parses the email and calls the the quickadd function
  • In cpanel setup a forwarder and pipe it to a program of TOGcal.php
<?php //GoogleCal-Functions.php

require_once 'Zend/Loader.php';
Zend_Loader::loadClass('Zend_Gdata');
Zend_Loader::loadClass('Zend_Gdata_ClientLogin');
Zend_Loader::loadClass('Zend_Gdata_Calendar');

// Enter your Google account credentials
$email = '[email protected]';
$passwd = 'MyPass';
$ourCal = 'Cal Name';
$ourCalUrl = '';
try {
 $client = Zend_Gdata_ClientLogin::getHttpClient($email, $passwd, 'cl');
 }
catch(Zend_Gdata_App_AuthException $ex)
{
    echo "Unable to authenticate";
    exit(1);
 }

$cal = new Zend_Gdata_Calendar($client);

$calFeed = $cal->getCalendarListFeed();

foreach ($calFeed as $calendar)
{
    if ($calendar->title->text == $ourCal)
 {
  //$ourCalUrl = explode('/',$calendar->id);
  //$ourCalUrl = 'http://www.google.com/calendar/feeds/'. $ourCalUrl[6] . '/private/full';
  $ourCalUrl = $calendar->getSelfLink()->getHref() . '/private/full';
  $ourCalUrl = str_replace("default/", "",$ourCalUrl);
 }
 //echo $calendar->title->text . " || " . $calendar->getSelfLink()->getHref() . "
";
}
 //echo $ourCalUrl;
 //echo $client->getUri(true);
 //createQuickAddEvent ($client ,$ourCalUrl,'WO Test at Jun 2, 2008 8:00am - Jun 6, 2008 5:00pm');
 //createEvent($client,$ourCalUrl);

function createQuickAddEvent ($client, $URI = NULL, $quickAddText) {
  $gdataCal = new Zend_Gdata_Calendar($client);
  $event = $gdataCal->newEventEntry();
  $event->content = $gdataCal->newContent($quickAddText);
  $event->quickAdd = $gdataCal->newQuickAdd(true);

  $newEvent = $gdataCal->insertEvent($event,$URI);
  return $newEvent->id->text;
}

/**
 * Creates an event on the authenticated user's default calendar with the
 * specified event details.
 *
 * @param  Zend_Http_Client $client    The authenticated client object
 * @param  string           $title     The event title
 * @param  string           $desc      The detailed description of the event
 * @param  string           $where
 * @param  string           $startDate The start date of the event in YYYY-MM-DD format
 * @param  string           $startTime The start time of the event in HH:MM 24hr format
 * @param  string           $endDate   The end date of the event in YYYY-MM-DD format
 * @param  string           $endTime   The end time of the event in HH:MM 24hr format
 * @param  string           $tzOffset  The offset from GMT/UTC in [+-]DD format (eg -08)
 * @return string The ID URL for the event.
 */
function createEvent ($client, $URI = NULL, $title = 'Tennis with Beth', $desc='Meet for a quick lesson', $where = 'On the courts',$startDate = '2008-06-20', $startTime = '9:00',$endDate = '2008-06-20', $endTime = '14:00', $tzOffset = '-04')
{
  $gc = new Zend_Gdata_Calendar($client);
  $newEntry = $gc->newEventEntry();
  $newEntry->title = $gc->newTitle(trim($title));
  $newEntry->where  = array($gc->newWhere($where));

  $newEntry->content = $gc->newContent($desc);
  $newEntry->content->type = 'text';

  $when = $gc->newWhen();
  $when->startTime = "{$startDate}T{$startTime}:00.000{$tzOffset}:00";
  $when->endTime = "{$endDate}T{$endTime}:00.000{$tzOffset}:00";
  $newEntry->when = array($when);

  echo $URI."||".$title."||".$desc."||".$where."||".$startDate."||".$startTime."||".$endDate."||".$endTime."||".$tzOffset;
  $createdEntry = $gc->insertEvent($newEntry, $URI);
  return $createdEntry->id->text;
}
?>
#!/usr/bin/php -q
<?php
//TOGcal.php
//Takes the subject and uses quickadd to create an event.
include "GoogleCal-Functions.php";

$msg = "";
$email ='';
$fd = fopen("php://stdin", "r");
while (!feof($fd))
{
 $email .= fread($fd, 1024);
}
fclose($fd);
$msg .= "got Email || ";

$mail = mailparse_msg_create();
mailparse_msg_parse($mail,$email);
$struct = mailparse_msg_get_structure($mail);
$section = mailparse_msg_get_part($mail, "1");
$info = mailparse_msg_get_part_data($section);

$msg .= $info['headers']['from'] . " || " . $info['headers']['subject']  . " || ";

//valid sending domains
if (preg_match('/@mydomain\.com/', $info['headers']['from']))
{
 createQuickAddEvent($client,$ourCalUrl,$info['headers']['subject']);
 $msg .= "regex matched || ";
} 
mailparse_msg_free($mail);

//emailError($msg);


?>