Ubuntu 9.04 - USB Dialup - Juno - Connect

My Mom uses Juno’s dialup service to connect to the Internet and for email. Her HP laptop (running Windows) was infected with something, and had really become unusable, it was so slow.

I took it home where my most valuable tool is a high-speed Internet connection.

After many tries, this is the general sequence of operations that worked.

  1. Install Ubuntu 9.04. Other versions may work, I chose this because Linuxant had drivers to support the internal modem. It’s nice.
  2. Run the upgrades offered.
  3. Restart
  4. The internal modem just wouldn’t work, so I bought an external USB modem from Best Buy. Zoom Modem, Model 3095.
  5. Followed the installation instructions and found that this laptop isn’t supported (it’s an x86_64). Used the link above and built the driver from the source. Many thanks to Linuxant.com.
  6. Added the user to dip and dialout groups
  7. Installed Gnome PPP, and Network
  8. Use sudo wvdialconf to configure wvdial
  9. Manually edited /etc/wvdial.conf to add in the Juno phone numbers, username and password
  10. Restart
  11. Tested the connection using wvdial, it worked. Then tested with Gnome PPP, it worked. Finally, used Network and PPP to connect, and browsed to juno.com
  12. Since I have a free account, Juno runs in a limited mode, but it is running. If you have a paid Juno account, it still won’t work with Linux. I recommend http://dialup4less.com as an alternate ISP.

Ubuntu is really nice to work with.

Hack Attack

For the last year or so, I have a site that sends me an email listing all the new and modified files on the server.

This morning, these entries caught my eye:

/var/www/html/
/var/www/html/c99.php

The c99 file was not supposed to be on the server.

Listing the /var/www/html directory, I found:

-rw-r–r– 1 nobody nobody 7293 Aug 1 04:58 (at sign).php
-rw-r–r– 1 nobody nobody 162032 Jul 31 05:57 c99.php
-rw-r–r– 1 nobody nobody 0 May 23 01:36 index.html
-rw-r–r– 1 nobody nobody 44283 May 23 01:36 Dont.Touch.php

I went back in my email Inbox, and found that the May 23 email was never received - cron had stopped on the server, and a ticket was sent to restart it.

The hosting company recommended I update some file and directory permissions, which I did, with the following commands:

find -type f | xargs chmod 644
find -type d | xargs chmod 755

These set permissions for a files to 644, and all directories to 755.

Tarred up the files and sent them to the hosting company, along with some notes.

On the bright side - nothing was lost, and the cleanup was pretty straightforward.

The error log showed execution attempts, which failed, and that IP address has been blocked.

Hack was not on this server.

An Ounce of Performance and Prevention

The Wicked Good Gallery was a lot of fun to build. It meets the stated requirements, I like the design, and I learned some good stuff.

One issue that always concerns me is performance. The Wicked Good Gallery demo has seven images, and on each page load, it reads the image directories, tests for a thumbnail and detailed image, and if they don’t exist, it creates them from the first .jpg in the directory it finds. The issue is that in most cases, when images are posted, they won’t change. This isn’t a versioned gallery, only the last image uploaded will be offered to site visitors.

For that reason, you can assume that the only time you need to test for new files is when the list of directories changes. You can further extend it to only rebuild new directories, but then you risk the problem of only testing for content in new directories, not refreshing any existing images.

Therefore, a simple caching solution was implemented. When the page loads, the code tests for the presence of a cache file. If the file is present, it compares the directories listed in the cache file to those it reads on the server. It they match, the cached list of artwork is used, otherwise, the cache is rebuilt.

$bUpdateCache=false;
$aDirectoryCache=array();
if (is_file($sDirectoryCache))
        include $sDirectoryCache;
else
        $bUpdateCache=true;
$aDirectories=glob($sArtworkDir.'/*');
if ($aDirectoryCache!=$aDirectories)
{
        foreach ($aDirectories as $k => $v)
        {
                if (is_file($v.'/'.$sArt) && is_file($v.'/'.$sThumb))
                        $aPieces[]=$v;
                else
                        if (make_images($v,$sArt,$iArtHeight,$sThumb,$iThumbHeight))
                                $aPieces[]=$v;
        }
        $bUpdateCache=true;
}
else
        $aDirectories=$aDirectoryCache;
if ($bUpdateCache)
        file_put_contents($sDirectoryCache,'<?php $aDirectoryCache='.var_export($aDirectories,true).';'.PHP_EOL.
                '$aPieces='.var_export($aPieces,true).'; ?>');

There was about a 0.0002 second improvement in performance. Although that sounds trivial, more rigorous testing, with more images, would likely justify the implementation. There is a performance penalty if the cache is removed, but it’s very small, since the cache is built with var_exports.

The prevention added was a base http://www.w3schools.com/TAGS/tag_base.asp tag. This tag ensures all files are drawn from the correct directories, while still allowing relative references in the code.


<base href="http://wirehopper.com/wickedgoodgallery/" />
<link rel="stylesheet" type="text/css" href="css/style.css" />

In this case, the base URL is http://wirehopper.com/wickedgoodgallery/, and the style tag will draw from http://wirehopper.com/wickedgoodgallery/css/style.css, regardless of any slashes submitted in the URI, the page will display properly, and future references, derived by page navigation (clicking on images and links) will be valid.

Quick Average Request Time from Apache access_log

First, you’ll need to add the time required to deliver the request into the access_log. In this case, a custom_log is created. Note the bolded ^%D at the end, which will deliver the time required to serve the request in microseconds ( http://httpd.apache.org/docs/2.2/mod/mod_log_config.html#formats ).

CustomLog logs/custom_log “%h %l %u %t \"%r\” %>s %b \"%{Referer}i\” \"%{User-agent}i\” ^%D

Add this into your Apache .conf file, as appropriate.

Next, restart Apache with apachectl restart. You can use apachectl configtest to check your editing.

The log file entry will look like this:

127.0.0.1 - - [14/Jul/2010:15:31:19 -0400] “GET /test/php/index.php HTTP/1.1″ 200 473 “-” “Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.2.4) Gecko/20100624 CentOS/3.6-8.el5.centos Firefox/3.6.4″ ^4097

The ^4097 indicates the number of microseconds to serve the request.

You’ll need the num_utils RPM, see the link above.

Get it and install it, like so:

wget http://suso.suso.org/programs/num-utils/downloads/rpm/num-utils-0.5-1.noarch.rpm
rpm -i num-utils-0.5-1.noarch.rpm

Use the following commands to extract the times from the log:

grep index.php custom_log | cut -d ‘^’ -f 2

And then, you can average them, like so:

cd /etc/httpd/logs
grep index.php custom_log | cut -d ‘^’ -f 2 | average
2611.33333333333

This post courtesy of Lyrix, Inc. ( http://lyrix.com / http://mobiso.com)

Browser Based Audio Preview / Listen - IE6/7/+, FF2+ - HTTP/HTTPS

The following code segment is an extract from a Smarty template which allows you to embed Windows Media Player in a web page and use javascript to initiate playback. AUDIOFILE.WAV is a marker name, you will need to use a valid URL.

The code uses two different methods for Internet Explorer (IE) and Firefox (FF).

For IE, it uses an object tag and the object model to initiate playback with player.controls.play and stop. Note the assignment of the source URL and data, this allows you to change which audio (or video) is being played.

The FF approach uses a pop up, opened with window.open. This loads a very small page which includes the player tag. The pop up is named, so later requests will reload the same window.

The template uses $bFF as a flag to indicate whether to deliver the page content for IE or FF. $bFF is true if the user agent is Firefox, false otherwise. The template logic can be replaced with PHP.


{if !$bFF}
<object id="wmp_p" name="wmp_p" style="display:none" classid="clsid:6BF52A52-394A-11d3-B153-00C04F79FAA6" width="0" height="0"></object>
<script type="text/javascript">/* <![CDATA[ */
var sAudioFile='AUDIOFILE.WAV';
{literal}
var player=document.getElementById('wmp_p');
function StartMeUp()
{
        if (sAudioFile!='')
        {
            player.URL=sAudioFile;
            player.data=sAudioFile;
            player.controls.play();
        }
}
function ShutMeDown()
{
    player.controls.stop();
}
{/literal}
/* ]]> */
</script>
{else}
<script type="text/javascript">
/* <![CDATA[ */
var sAudioFile='AUDIOFILE.WAV';
{literal}
function StartMeUp()
{
        if (sAudioFile != '')
                window.open('player.php?'+sAudioFile,"player","toolbar=no, location=no, directories=no, status=no, menubar=no, scrollbars=no, resizable=no, copyhistory=no, width=275, height=95");
}
function ShutMeDown()
{
        if (sAudioFile != '')
                window.open('player.php?',"player","toolbar=no, location=no, directories=no, status=no, menubar=no, scrollbars=no, resizable=no, copyhistory=no, width=275, height=95");
}
{/literal}
/* ]]> */
</script>
{/if}
<a href="javascript:StartMeUp();" title="Listen" id="Preview" name="Preview"><img src="images/cp/16x16/actions/player_play.png" alt="Listen" /></a>

player.php


<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html lang="en-US">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>Audio Preview</title>
</head>
<body>
<div>
    <img src="images/cp/64x64/apps/arts.png" />
        /* Some code omitted for brevity */
    <!-- Some code omitted for brevity -->
    <object id="wmp_p" data="<?php echo $_SERVER['QUERY_STRING'];?>" type="application/x-ms-wmp" width="175" height="75" >
      <param name="autostart" value="true" />
      <param name="volume" value="10" />
      <param name="uiMode" value="mini" />
      <p>Error - the plugin has not loaded</p>
    </object>
</div>
</body>
</html>

Difficulties were encountered playing HTTPS audio with a self-signed certificate under FF. After research, the simplest resolution was to route audio requests through HTTP.

Resources:

http://www.w3schools.com/media/media_playerref.asp
http://port25.technet.com/pages/
http://support.mozilla.com/en-US/kb/Using+the+Windows+Media+Player+plugin+with+Firefox
For MP3s, you can use: http://docs.dojocampus.org/dojox/av/FLAudio

——————————-

This post courtesy of Lyrix, Inc. ( http://lyrix.com ) - Mobiso ( http://mobiso.com )