Raam Dev's


Archive for the ‘Linux’ Category

Dialog is a really useful utility for creating professional looking dialog boxes and menus within a shell script. I’m working on a boot-time script that allows the user to make system-level changes before the system has fully booted.

When testing my script from the command line, the dialog menu looked fine. However, whenever I set the script to start during boot (update-rc.d myscript.sh defaults, on Debian-based systems) here is what the menu looked like:

dialog display issues

UGH! It was barely usable. At first, I thought this would be an endlessly difficult problem to solve given my limited in-depth knowledge of Linux (I’m getting there!), but then I realized the main difference between the script running during boot and the script running after I had logged in was that my environment variables had not been loaded.

From the command line, I ran the env command to display all my current environment variables:

debian_vm:~# env
TERM=xterm-color
SHELL=/bin/bash
SSH_CLIENT=172.16.168.1 61315 22
SSH_TTY=/dev/pts/0
USER=root
MAIL=/var/mail/root
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/bin/X11
PWD=/root
LANG=en_US.UTF-8
PS1=\h:\w\$
SHLVL=1
HOME=/root
LANGUAGE=en_US:en_GB:en
LOGNAME=root
SSH_CONNECTION=172.16.168.1 61315 172.16.168.132 22
_=/usr/bin/env

The three variables that caught my eye were TERM, SHELL, and LANG. After a little trial and error, I discovered setting the LANG variable fixed the display issues with dialog! I added the following near the top of my script:

export LANG=en_US.UTF-8

Now when my script loads during boot, everything looks correct:

dialog display issues fixed
(0) Comments

A few months ago I wrote a post about creating Amazon S3 HMAC Signatures without PEAR or PHP5. One of the things I was using that PHP script for was to feed the necessary information to a bash script hosted on a remote machine. The bash script was to upload a file via POST to Amazon S3 using the information provided.

Since CURL was already installed on the remote machine, I wanted to use that to do the actual uploading. I found very little help on the net regarding how to do this with CURL so here you go:

eris:~ raam$ curl \
-F "key=screenshots/current_screenshot.jpg" \
-F "acl=public-read" \
-F "AWSAccessKeyId=2EO6H8MX1X8YWEA0V432" \
-F "Policy=eyAiZXhwaXshdGlvbpI6ICIyMDA4LTErLTAxVDtyOjAwOjAwLjAsMFoiLAogICJjb25kaXRpb25zPjogWwoJeyJidWNrZXQiOiAiczNwaG90b3MubW9hcHAubmV0IiB9LAogICAgWyJzdGFydHMtd2l0aCIsICIka2V5IiwgIkxpdmVTaG90cy8iXSwKICAgIHsiYWNsIjogInB1YmxpYy1yZWFkIiB9LAoJWyJlcSIsICIkQ29udGVudC1UeXBlIiwgImltYWdlL2pwZWciXSwKICBdCn0K" \
-F "Signature=20uh08kU75ADHL49NyhYRgZW8BY=" \
-F "Content-Type=image/jpeg" \
-F "file=@current_screenshot.jpg" \
http://screenshots.ekarma.net

Keep in mind this assumes the current_screenshot.jpg file is in your current directory.

(0) Comments

My Notes from The Last HOPE

Wednesday, July 23rd, 2008 - Filed in Blog Entries, HOWTO's, Linux, Networking, Security, Technology, Web

Here are my notes from The Last HOPE. I started taking notes late, so unfortunately I don’t have notes from all the talks I attended.

Ghetto IDS and Honeypots
* An Evening with Berferd
* Low interaction honeypots: Nepenthes, honeyd, Honeytrap
* Monitor both Honeyd and Nepenthes with Prelude IDS

Monitoring Snort
* SGUIL
* BASE
* SnortSnarf

Remember, tcpdump (a common packet sniffer) writes data in pcap format which ngrep, WireShark, or Snort can process.

Kevin Mitnick - Featured Speaker
* Flowroute + Asterisks can be used to unmask Caller ID (I tested Mitnick’s setup by calling his phone… my blocked number showed up!)

PenTest Labs Using LiveCDs by Thomas Wilhelm
* de-ice.net
* BackTrack, Slax

PenTesting from Firefox URLs:
* isecom.org/osstmm/
* owasp.org/index.php/Main_Page/
* csrc.nist.gov/publications/PubsSPs.html
* vulnerabilityassessment.co.uk/Penetration Test.html
* centralops.net
* nmap-online.com
* hackerwhacker.com (similar to GRC)

Remember, use TOR when doing active tests!

More useful URLs:
* gdataonline.com/seekhash.php
* passcracking.com
* hash.insidepro.com
* md5this.com
* gdataonline.com
* us.md5.crysm.net
* md5.rednoize.com
* milw0rm.com
* freerainbowtables.com
* netcraft.com

Pen Testing the Web with Firefox

Firefox Extensions:
* FireCat
* ExploitMe (XSS-Me, SQL Inject-Me, Access-Me)
* Tamper Data
* Passive Recon
* Add N Edit Cookies
* Firebug
* HackBar
* Web Developer
* xssed.com

Using Firefox as a Front-End: Proxies
* Tor Button
* Paros Proxy
* SPIKE Proxy
* Burp Proxy

Web Frontends
* Metasploit
* FastTrack
* Inprotect (web interface for Nessus and Nmap)
* BASE (web front-end for Snort)

Use Firefox profile manager to install different selections of extensions to help with memory concerns.

FEBE (Firefox Environment Backup Extension)
CLEO (Compact Library Extension Organizer)
OPIE (Import/Export extension preferences)

Places/Things to hack “safely”
* OWASP WebGoat Project
* PwnOS (VMWare image, requires forum login)
* Your own VMWare lab

Identification Card Security: Past, Present, Future

The Complete Amature - ID Making Operating Guide by Doug Farre

* Epson Stylus R800 photo printer
* Laminator
* Dye cutter
* Magnetic stripe encoder
* Custom rubber stamp (simonstamp.com)
* Black light
* Scanner
* Signature pad
* Photoshop
* brainstormidsupply.com

Minimal needed materials:
* Laser Teslin
* Laminates
* Pearl-Ex pigment powders
* Ultraviolet pigment powder
* Transparent base

(Get these from practicingperfection.7p.com. That site is down as of right now, so you need the guy’s email address to contact him.)

Documentation on ID security can be found at idsysgroup.com.

Books to Read
* 1491: New Revelations of the Americas Before Columbus
* Hackers: Heroes of the Computer Revolution
* The Art of Intrusion: The Real Stories Behind the Exploits of Hackers, Intruders & Deceivers

Random URLs:
* foodhacking.com
* hackerspaces.org
* telephreak.org

(0) Comments

When the LogWatch report from yesterday (for web.akmai.net) arrived in my Inbox, it had over 20,000 failed SSH login attempts. Today I decided it was finally time to do something about all those attacks.

After looking around a bit, I found several different solutions. Some solutions utilized firewall rules and others monitored your /var/log/secure (or /var/log/auth.log) log files for multiple failed login attempts and then added those IPs/Hosts to the /etc/hosts.deny file.

I decided to go with the latter method and quickly found a nice tutorial for setting up DenyHosts (be sure to download the latest version (2.6 as of this writing) instead of the older version 2.0). Rather than reinvent the wheel, here is what the DenyHosts website says about itself:

What is DenyHosts?

DenyHosts is a Python script that analyzes the sshd server log messages to determine what hosts are attempting to hack into your system. It also determines what user accounts are being targeted. It keeps track of the frequency of attempts from each host.

Additionally, upon discovering a repeated attack host, the /etc/hosts.deny file is updated to prevent future break-in attempts from that host.

An email report can be sent to a system admin.

Since I was setting up DenyHosts on a RedHat-based machine (CentOS) and not a Debian-based machine, I needed to change this line:

update-rc.d denyhosts defaults

to this:

chkconfig denyhosts --add

Other than that, the installation steps were just as the tutorial described. I decided to enable the ADMIN_EMAIL option so that I would receive an email every time something was added to hosts.deny, but within minutes of starting DenyHosts I had a dozen attacks with a dozen emails on my BlackBerry. I had to disable ADMIN_EMAIL to stop the spamming!

To make sure DenyHosts was working properly I tried logging in with the wrong password three times. When I tried to connect again, here is what I received:

ssh root@akmai.net
ssh_exchange_identification: Connection closed by remote host

DenyHosts also has the ability to report to a central server the hosts that are trying to break in and you can also download a list of hosts that have been reported by others. I choose to opt out of doing this for now. The DenyHosts statistics page is pretty cool. Notice how the majority of the hosts come from China? Hmm.

UPDATE:
I quickly discovered that DenyHosts was adding my IP address to the hosts.deny file. When I watched /var/log/secure I discovered the problem:

Jun 13 20:18:46 web sshd[5959]: reverse mapping checking getaddrinfo for 75-147-49-211-newengland.hfc.comcastbusiness.net failed - POSSIBLE BREAKIN ATTEMPT!
Jun 13 20:18:46 web sshd[5959]: Accepted publickey for fooUser from ::ffff:75.147.49.211 port 57926 ssh2
Jun 13 20:18:48 web sshd[5994]: Did not receive identification string from ::ffff:75.147.49.211

I’m not entirely sure how to fix this, but for now I added my IP address to /usr/share/denyhosts/data/allowed-hosts (I had to create this file) which prevents DenyHosts from blocking my IP no matter what (see this FAQ for more info). Also, I had to restart DenyHosts (/etc/init.d/denyhosts restart) before the change to allowed-hosts took effect.

(0) Comments

I’ve been doing some stuff at work using Amazon S3 to store files and during my testing I uploaded a ton of files that didn’t need to be there. Unfortunately, the command line tool I’m using, s3cmd, does not allow me to delete multiple files at once. There is no way to do a wild-card delete. This means I would need to get the full path to each object and delete them one by one:


./s3cmd del s3://s3.ekarma.net/img/1205794432gosD.jpg
Object s3://s3.ekarma.net/img/1205794432gosD.jpg deleted
./s3cmd del s3://s3.ekarma.net/img/1205794432g34fjd.jpg
Object s3://s3.ekarma.net/img/1205794432g34fjd.jpg deleted

Yea, there’s no way I’m doing that for over 200 objects. I mean come on, there are tools to automate this kind of stuff! So I created s3delmany.sh:

#!/bin/sh
# -------------------------
# s3delmany.sh
# Author: Raam Dev
#
# Accepts a list of S3 objects, strips everything
# except the column containing the objects,
# and runs the delete command on each object.
# -------------------------

# Redirect output to the screen
2>&1

# If not using s3cmd, change this to the delete command
DELCMD="./s3cmd del"

# If not using s3cmd, change $4 to match the column number
# that contains the full URL to the file.
# This basically strips the rest of the junk out so
# we end up with a list of S3 objects.
DLIST=`awk 'BEGIN { print "" } { print $4, "\t"} END { print ""}'`

# Now that we have a list of objects,
# we can delete each one by running the delete command.
for i in "$DLIST"; do $DELCMD $i
done

Download
s3delmany.zip

Installation
1. Extract s3delmany.zip (you can put it wherever, but I put it in the same directory as s3cmd).
2. Edit it with a text editor and make sure DELCMD is set correctly. If you’re not using s3cmd, change it to match the delete object command for that tool.
3. Make it executable: chmod 755 s3delmany.sh

Usage
If you’re using s3cmd and you placed s3delmany.sh in the /s3cmd/ directory, you should be able to use the script without modifying it. The script works by taking a list of objects and running the delete command on each one.

To pass s3delmany.sh a list of objects, you can run a command like this:

./s3cmd ls s3://s3.ekarma.net/img/ | ./s3delmany.sh

This will delete all objects under /img/. Make sure you know the output of your s3cmd ls command before you pass it to s3delmany.sh! There is no prompt asking if you’re sure you want to delete the list, so get it right the first time!

Hint: s3cmd doesn’t allow you do use wild-cards, but when you run the ls command, you can specify the beginning of an object name and it will only return objects starting with that. For example, s3cmd ls s3://s3.ekarma.net/img/DSC_, will return only those objects that begin with DSC_.

Alternate Usage
If you have a text file containing a list of S3 objects that you want to delete, you can simply change print $4 to print $1 and then do something like this:

cat list.txt | ./s3delmany.sh

By the way, print $4 simply tells s3delmany.sh that the S3 objects are in the 4th column of the data passed to it. The ./s3cmd ls command outputs a list and the object names are in the 4th column. The awk command expects the columns to be separated by tabs (\t).

If you have any questions or comments, please don’t hesitate to use the comment form below!

(2) Comments

I’m a little paranoid when it comes to wireless security. Even if I’m on an encrypted wireless network, I won’t access any of my bank accounts or login to any website that requires a password without securing my traffic with an additional layer of security using SSH tunneling.

SSH tunneling can also be used to circumvent network-based restrictions in the workplace or on a free public wifi hotspot, giving you the freedom to browse whatever websites you want. If implemented on an OS networking level, you can even use the tunnel for your email and other applications. However the focus of this post is on using SSH tunneling to secure your web traffic.

Here is a quick list of what you’ll need:

  • Firefox or Internet Explorer (this technique also works with Opera and Safari, although I don’t cover those here)
  • Putty (Windows); The terminal (Linux or OS X)
  • SwitchProxy Tool (nice-to-have Firefox Plugin)
  • Access to an *nix-based computer. This will probably be the most difficult to obtain and if you’re not familiar with Linux or OS X I recommend you ask a friend if they wouldn’t mind giving you an account on their Linux computer. You can try to find a free shell that allows port forwarding, but they are rare.

Setting up the SSH Tunnel

Windows

Since Windows doesn’t have an SSH client built in, you will need to use the wonderful SSH client application called Putty. After you’ve downloaded and launched Putty, you should be presented with the main screen. Fill in the Host Name (or IP address) field with that of your Linux computer and be sure to select SSH from the Connection type.

On the left column of options, select Connection -> SSH -> Tunnels. Enter 9000 in the Source port field, select Dynamic from the option at the bottom, and then click Add. Your screen should now look something like this:

Note: If you don’t see the Dynamic option in Putty, make sure you have the latest version.

Now go ahead and click the Open button to connect to and login to your Linux computer. Once you have successfully logged in, the tunnel will be open and you can proceed to configure your web browser to use the tunnel.

Linux/OS X

Since you’re using a *nix based system, your computer already has everything it needs to setup an SSH tunnel. Simply access the terminal (Applications -> Utilities -> Terminal.app on OS X) and connect to the remote Linux computer as follows:

ssh -l -D 9000

After logging into the remote computer, the dynamic SSH tunnel will be opened and we can continue to configuring the web browser.

Configuring the Web Browser to use the SSH Tunnel

Firefox with SwitchProxy Tool plugin (the method I use)

Download and install the SwitchProxy Tool plugin. After installing the plugin, open its configuration window (Tools -> Add-ons -> SwitchProxy Tool -> Preferences on OS X). This will open the basic configuration window for the plugin. Click Manage Proxies and then Add. Choose Standard for the proxy configuration type and click Next. Fill in the fields as shown below.

After saving the connection, you should be able to use the plugin to easily switch between browsing through the SSH tunnel and browsing without it. I have it configured to show in the Firefox Status Bar, as I find that to be the easiest method of toggling between the two:

Firefox without SwitchProxy Tool

Although SwitchProxy Tool to easily switch my proxy settings, I will also explain how to configure the browser without the plugin.

Open the Firefox Preferences (Firefox -> Preferences on OS X) and click the Advanced icon at the top. In the connection section, click the Settings... button. Choose Manual proxy configuration and fill in the SOCKS Host and Port fields as shown below.

Internet Explorer

From the Internet Explorer menu, choose Tools -> Internet Options. Select the Connections tab and then click the LAN Settings button. Enable the Use proxy server for your LAN option and click Advanced.

In the Servers section, make sure all the fields are empty except for the Socks field. Type localhost in the Socks Proxy address field and 9000 in the Port field. Your screen should look something like this:

Click the OK button all the way back to your browser. You should now be browsing the Internet securely through the SSH tunnel! An easy way to confirm this is to disconnect from the Linux computer by closing Putty and checking if you can still browse the web. Since the browser has been configured to use the tunnel, you won’t be able to browse the web if that tunnel is closed.

If you wish to revert back to browsing the web normally, simply uncheck the Use proxy server for your LAN option in LAN Settings.

(0) Comments

Using .htaccess to force SSL (https)

Monday, December 17th, 2007 - Filed in Blog Entries, HOWTO's, Linux, Security, Technology, Web

I created a web application at work today and instead of implementing a full-blow authentication system (or spending time integrating it with our current authentication system) I decided to use HTTP Authentication.

Anyone who knows anything about HTTP Auth will tell you that it’s very insecure. To add a level of security I used an .htaccess file (placed in the directory of the application) to force the use of SSL (https), which uses the certificate we’ve already installed to secure the rest of the site.

Here is what I added to the .htaccess:

RewriteEngine On
RewriteCond %{SERVER_PORT} 80
RewriteCond %{REQUEST_URI} /path/to/app/
RewriteRule ^(.*)$ https://www.domain.com/path/to/app/$1 [R,L]

If you’re already using an SSL certificate on your site, this is a great and easy way to secure HTTP Authentication.

(0) Comments

Using Procmail to Mark As Read

Wednesday, November 14th, 2007 - Filed in Blog Entries, HOWTO's, Linux, Technology

I’ve seen a couple of blog posts explaining how to mark Maildir messages as read with procmail. All of them point to a thread on the procmail mailing list as the source of this solution. However, all of them fail to make any kind of attempt at explaining whats going on. After some trial and error, I was able to learn what was happening. First the snippet of procmail code:

:0
* conditions
{
  foldername=whatever

  :0c
  .$foldername/ # stores in .$foldername/new/

  :0
  * LASTFOLDER ?? /\/[^/]+$
  { tail=$MATCH }

  TRAP="mv $LASTFOLDER .$foldername/cur/$tail:2,S"

  HOST
}

OK, I’m some-what familiar with procmail, however this code was not very intuitive. Why does a copy of the message (:0c) get moved into $foldername? What is HOST and what does it do? I will attempt to explain:

* conditions
This can be whatever you want. In my case, my Blackberry forwards a copy of all sent email to my inbox so that I can store it in the sent folder for future reference. However, I don’t want to see “new” messages in my sent folder. I want them to be moved there and marked as read. All messages coming from my Blackberry have a From address of test@example.com, so my condition is ^From.*test\@example\.com. I make the assumption that I won’t be emailing myself (I have a separate email account for that).

foldername=whatever
This is just storing the path to the folder we’re going to work with. In my case, I’m using my sent folder: foldername=/home/raam/mail/sent

:0c
.$foldername/

This places a copy of the message in the /new directory. This confused me, since the point of this code was to mark messages as read. But I discovered this step was necessary for the next few lines to work.

:0
* LASTFOLDER ?? /\/[^/]+$
{ tail=$MATCH }

First, let’s read what LASTFOLDER is according to the procmail documentation:

This variable is assigned to by procmail whenever it is delivering to a folder or program. It always contains the name of the last file (or program) procmail delivered to. If the last delivery was to several directory folders together then $LASTFOLDER will contain the hardlinked filenames as a space separated list.

OK, so in this case, LASTFOLDER would contain the full path to the email that was copied to $foldername in the previous step. I’m not entirely sure what the rest of the commands do, but they’re necessary.

TRAP=”mv $LASTFOLDER .$foldername/cur/$tail:2,S”
Deciphering the mv command is pretty simple. It moves the email that we copied to $foldername to the /cur/ directory and renames it to end with :2,S. Cool, that makes the email client see the message as read. But what is TRAP? Again, let’s RTFM and find out what TRAP is used for:

When procmail terminates of its own accord and not because it received a signal, it will execute the contents of this variable. A copy of the mail can be read from stdin. Any output produced by this command will be appended to $LOGFILE. Possible uses for TRAP are: removal of temporary files, logging customised abstracts, etc.

Interesting. But the next line is even more interesting!

HOST
What on Earth could this do? Well to my surprise it is directly linked to TRAP. Since the contents of TRAP will be executed when procmail terminates, we need a way of terminating procmail (for this block anyway). We do this with HOST. Here is a good explanation from another mailing list thread:

Lacking an explicit “exit” command in procmailrc, “HOST” in procmail is
what “exit $EXITCODE” would be in a shell.

So there you have it. I had no idea there would be so much happening behind these few lines of procmail code, but I’m glad I took the time to learn!

(6) Comments

Linux Uptime: 428 days

Wednesday, November 7th, 2007 - Filed in Blog Entries, Linux, Technology

18:02:11 up 428 days, 3:31, 3 users, load average: 0.14, 0.09, 0.09

This is my CentOS4 web server, which runs Akmai.net Web Hosting. Unfortunetely only a few days after taking this uptime reading, the server needed to be rebooted due to a bug in CPanel.

(0) Comments

SSH Client Keys

Tuesday, October 9th, 2007 - Filed in Blog Entries, HOWTO's, Linux, Security, Technology

SSH Client Keys allow you to quickly login to a remote server via SSH without typing your password. This is very useful if you login to a remote *nix server on a regular basis or if you want to automate scripts that need to remotely connect using SSH (using commands such as rsync or cvs over SSH).

I have used SSH keys for awhile now, but whenever I setup a new server I seem to draw a blank when trying to remember how to set them up. Each time I end up searching Google for “SSH Client Keys” and clicking on the excellent O’Reilly page “Quick Logins with ssh Client Keys“. I really don’t like duplicating information that is already available on the web, but I felt it was necessary to explain a couple of points the O’Reilly page misses, particularly about the authorized_keys2 file on the server.

Because I’ve followed the setup procedure so many times, I usually only need to glance at the directions to remember how its done. However, it was doing this that caused me much frustration today. I discovered that it is very important that the server-side ~/.ssh directory (and all files inside) are chmod 0700(!), otherwise this whole process is pointless!

Before I review how to setup SSH Client Keys, let me give a brief overview of the files involved:

Client-side:
~/.ssh/id_rsa (private key, chmod 0600)
~/.ssh/id_rsa.pub (public key, chmod 0655)

Server-side:
~/.ssh/authorized_keys2 (holds a list of public keys, chmod 0700)

Now that you know what files are needed, let me explain how to go about creating them. The procedure for getting SSH keys setup is rather straightforward. First of all, if you’ve never used SSH keys before you probably need to generate a public/private key pair on the client-side (your workstation). From your home directory, run the following command:

$ ssh-keygen -t rsa

When prompted, leave the default options as they are (that includes leaving the passphrase option blank) and simply press Enter until you’re back at your command prompt. If you did not already have a ~/.ssh directory, this command will create the directory and place two files inside: Your private id_rsa and the public id_rsa.pub version of it to use on remote servers.

Now that you have the Client-side files you need, it’s time to create the necessary server-side files and copy the contents of your public key file (id_rsa.pub) to authorized_keys2 on the server-side. The procedure outlined on the O’Reilly page assumes you don’t already have any SSH keys setup on the remote server and simply replaces authorized_keys2 with the contents of id_rsa.pub. The two commands you are instructed to run are:

$ ssh server "mkdir .ssh; chmod 0700 .ssh"
$ scp .ssh/id_rsa.pub server:.ssh/authorized_keys2

While this is fine for those who are setting the keys up for the first time on a new server/account, it may slip up those who already use them. If the file already exists, it will overwrite any existing keys listed in the authorized_keys2 file. The authorized_keys2 file is simply a text file list of the public keys (the contents of ~/.ssh/id_rsa.pub on the client-side).The easiest thing to do if the file already exists on the server-side is to simply copy the contents of your ~/.ssh/id_rsa.pub file, SSH over to the server, open authorized_keys2, and paste your key at the bottom of the list.

Now you should be able to type ssh server and automatically login without typing a password!

(0) Comments

Using wget to run a PHP script

Saturday, October 6th, 2007 - Filed in Blog Entries, HOWTO's, Linux, PHP, Programming, Technology, Web

wget is usually used to download a file or web page via HTTP, so by default running the wget http://www.example.com/myscript.php would simply create a local file called myscript.php and it would contain the contents of the script output. But I don’t want that — I want to execute the script and optionally redirect its output somewhere else (to a log file or into an email for reporting purposes). So here is how it’s done:

$ wget -O - -q http://www.example.com/myscript.php >> log.txt

According to the wget man page, the “-O -” option is used to prevent wget from saving the file locally and instead simply outputs the result of the request. Also, wget normally produces it’s own output (a progress bar showing the status of the download and some other verbose information) but we don’t care about that stuff so we turn it off with the “-q” option. Lastly, the “>> log.txt” redirects the output of the script to a local file called log.txt. This could also be a pipe command to send the output as an email.

There is an incredible amount of power behind wget and there are a lot of cool things you can use it for besides calling PHP scripts from the command line. Check out this LifeHacker article for a bunch of cool uses.

(0) Comments

A couple of months ago I wrote about a solution to recursively rename multiple files on a Linux system. The problem with that solution was that the script needed to be saved as a file called rename and then chmod 755 to make it executable.

Today, while writing a script for my ASAP application, I found a much easier one line solution which uses commonly installed command line tools:

$ for i in `find . -name "*.php5"` ; do mv -v $i ${i/\.php/\.php5/}; done

This chain of commands searches for all files containing .php5 and renames them to .php. The most obvious limitation of this solution is that if a filename or directory contains .php5, it will also be renamed. So if, for some wacky reason, you had a directory called /my.php5.files/, that directory would be renamed to /my.php.files/. Similarly, a file named my.php5.example.php would be renamed to my.php.example.php.

For my application, this one liner worked fine as I simply added a warning to the top of my script. If anyone knows how I can easily modify that command to ignore all directories (I didn’t see anything in the find command syntax that might help), I would greatly appreciate the information!

(2) Comments

Moving a CVS 1.12 repository to CVS 1.11

Monday, September 24th, 2007 - Filed in Blog Entries, HOWTO's, Linux, Technology

Over the weekend I moved my entire CVS repository from my home server to a domain hosted on the dedicated web server for my web hosting company. From what I read online, it was as simple as copying all the files to the new location. This appeared to work, but when I tried to create a new project and share it to the repository using Eclipse, I received the following error:

CVS Error

Hmm, unrecognized keyword 'UseNewInfoFmtStrings'. I tried searching Google and although I didn’t find very much in the way of a solution, there were hints to the error possibly relating to differences in CVS versions. So I checked my home server version: CVS 1.12.13. Then I checked the version of CVS on my web server: CVS 1.11.17. Ah ha!

My next thought was to upgrade CVS on my web server. But then I discovered my web server (CentOS 4) doesn’t have the CVS 1.12 package available because only stable packages are supported. I decided it was best to keep the server stable and starting looking for a way to “downgrade” the 1.12 repository to make it compatible with 1.11.

My eventual solution was to backup /home/dev82/cvsroot/CVSROOT/history, which contains the history information for all the files in the repository, and then delete the /home/dev82/cvsroot/CVSROOT/ directory. After this, I simply ran the following command to recreate CVSROOT and make it compatible with CVS 1.11:

root@web# cvs -d /home/dev82/cvsroot/ init

With the fresh CVSROOT directory in place, I copied the history file back to /home/dev82/cvsroot/CVSROOT/, overwriting the existing one that the cvs init command created.

My biggest worry with doing this was possibly losing history information or somehow being unable to restore files, etc. However, I was able to successfully, create, commit, and restore files from the history. I also had no errors creating new projects and sharing them with the CVS repository.

If anyone knows of a better solution, or has any information on what potential problems following this procedure might have, please leave a comment and let me know!

IMPORTANT UPDATE: I discovered any new files I committed to my repository were being saved to the ./Attic directory. The ./Attic directory is used by CVS for files that have been deleted. If someone checks out a version of the code where that file existed, CVS will pull the file out of the Attic and allow it to be checked out. The funny thing was that my newly committed file still checked out normally even though it only existed in the Attic on the server.

Eventually, I concluded the trouble of moving a 1.12 repository to a server running CVS 1.11 wasn’t worth the trouble. I checked out the latest versions of all my projects, deleted the CVS meta-data from them (Eclipse allows you to do this automatically when you disconnect a project from a CVS repository), and then created a new clean repository and checked all the projects back in. My history information is gone, but if I ever discover I really need an old version of a file, I still have a copy of the original repository on my home server.

(0) Comments

Making iTerm and naim play nicely

Friday, August 3rd, 2007 - Filed in Blog Entries, HOWTO's, Linux, OS X, Technology

I’ve started using iTerm as my terminal client on Mac OS X. Previously, I was using the Terminal.app which comes with OS X, but that has its limitations. It also doesn’t look as pretty as iTerm does when I’m using naim, the console based messaging client I use to talk on IRC, GoogleTalk, and AIM.

Out of the box, iTerm works really well and there wasn’t very much I customized to make it look the way I wanted. I didn’t see an option in Terminal to disable bold fonts, however iTerm has that option and it makes naim look much nicer:

Of course, I can’t forget to mention one of the best features of iTerm: tabs! Yes, I can have five or six terminal windows open, and they will only take up the space of one window. Detaching a tab is as simple as dragging it away from the main window. OK, back to the point of this post.

When I started using a G4 Mac several months ago, I was using Terminal to access naim. After a lot of digging around on the web, I finally discovered how to map the keys in Terminal so they work as expected to control naim (changing screens, scrolling through the buddies list, etc). I documented my discoveries on the NaimWiki. However, to my disappointment and frustration, iTerm’s default key bindings did not work with naim out of the box. I figured it would be as simple as following the steps I followed for Terminal, but that wasn’t the case.

There were two problems I needed to solve: Fix the backspace key and the home, end, page up, and page down keys. The backspace key was Yfixed with the help of this blog post. I simply modified the ‘delete’ key mapping for the iTerm Keyboard Profile I was using and changed the hex code being sent from 7f to 0×08.

I then needed to add new entries for the other keys to work properly. For each of these keys, add a new mapping, select the key, choose ‘Send escape sequence’ for the action and enter the appropriate sequence:

[1~ (home)
[4~ (end)
[5~ (page up)
[6~ (page down)

That’s it! You should now be able to change connections (IRC, AIM, etc) by holding down fn and pressing delete. To scroll through your buddies, or through channels on IRC, simply hold fn and press home or end. To page up and down through the conversation window, use fn and page up or page down.

You can find my addition of this information to the NaimWiki here. If you have your own tips for using iTerm, please let me know!

(0) Comments

My Debian GNU/Linux server Pluto, which is located in my apartment in Cambridge, is running on a Mac Mini (PowerPC). Over the past few days, I’ve had several power outages. When the power comes back on, my Windows computer turns back on and, if I need to, I can remotely connect to it from the office. Pluto however, does not automatically turn back on. I need to physically turn it on when I get home from work. This is not acceptable!

On a PC, there is a BIOS option called PWRON After PWR-Fail. This simply turns the computer back on if the power goes out while it is running. Great, but the Mac Mini doesn’t have a standard BIOS; it has OpenFirmware! I did lots of Googling and came up with solutions specific to Mac OS X, but that doesn’t help me since I’m running Linux. I even discovered the command line utility pmset which can be used to modify power management settings from within OS X (and a nifty option called autorestart which causes the Mac to automatically restart after power failure). I thought maybe I could find the pmset utility for Linux and install that, but that turned up nothing as well.

Eventually, I found the answer in this forum post on an Ubuntu forum. It’s amazing how the Ubuntu operating system has created such a huge wealth of information for the Linux community. This huge pool of questions and answers has made finding solutions to common (or not so common) Linux issues much easier over the past few years.

As root, execute the following command:

echo 'server_mode=1' > /proc/pmu/options

You can confirm the changes have been made by running:

cat /proc/pmu/options

If server_mode=1, then you’re all set. You can try unplugging the power from your Mac Mini, waiting a few minutes, and plugging it back in. The Mini should turn on as soon as you plug in the power.

(6) Comments