Some of the functions I wanted to use my Motorola Droid for don’t have apps available unless you have root access.  So, I looked into rooting the phone.  This is a relatively easy process.  I watched a few videos and read a few tutorials before I rooted my Droid. The Cyanogenmod Wiki, DroidForums.Net, and the XDA-Developers Forum are especially good for information about rooting your Android device.

However, there was one video that was most helpful.  And, the Cyanogenmod Wiki – Motorola Droid: Full Update Guide was extremely helpful with installing Cyanogenmod 7.  The update files from the video were really helpful with the exception of the installation of SPRecovery.  The SPRecovery file from the video actually caused an error for me that didn’t allow the phone to boot.  However, the SPRecovery SBF file from the Cyanogenmod Wiki fixed the issue for me.

The first issue I ran into after rooting the phone was that the ROM Manager and the Android Market stopped working.  At first I thought I messed something up so I reset the the phone back to factory settings (which basically did nothing except remove all my contacts and the apps that I currently had installed, including ROM Manager).  The Android Market still didn’t work and I couldn’t link up my Google account anymore.  So basically, I had a stock rooted phone with no contacts on it.

When I started searching, I found right away that the Google Applications don’t work on a rooted phone.  Furthermore, the popular Cyanogenmod doesn’t allow you to access the Google Apps either, but there are updates you can install that will give you access to Google Apps.  The Cyanogenmod Wiki – Motorola Droid: Full Update Guide has a link to the Google Apps files.

Another issue I had was when I attempted to install an incorrect ROM and received this error when attempting to install Cyanogenmod in Clockwork Recovery.  I reflashed the phone and that fixed the problem.  After all the abuse my Droid has seen, I’m pretty convinced that you can’t brick it at this point.

My impressions of Cyanogemod 7 on the Motorola Droid: Nice ROM with good features, but too many bugs.  I tried both the version 7 Stable release and the Experimental (which doesn’t appear to be available anymore).  Each had it’s own specific set of bugs.  For instance, the Stable didn’t allow me to write to the SD card after awhile (didn’t seem like anything caused this in particular, except that I added more files to the SD card).  The screen started to freak out and not work right at all after 2 weeks on the Experimental.  I had to reflash in SPRecovery to a stock Froyo ROM to fix the issue.  Peter Alfonso has a nice listing of ROMs for the Motorola Droid on his site.  I just used the latest SBF flash file he had and reflashed my phone.

So, now I’m just running the stock Froyo ROM rooted.  Even though I’m not running a custom ROM at the moment, it’s still worth rooting the phone to run applications like OpenVPN, SSHTunnel, DroidWall, and Titanium Backup.  There are other custom ROMs available, such as MIUI.  And the Cyanogenmod group is always releasing updated versions, so I may try again in the future.  A friend of mine runs the Cyanogenmod nightlies on his Nexus and has not encountered any of the bugs that I had dealt with, so Cyanogenmod will work differently from phone-to-phone depending on the model.

If you end up rooting your phone, make sure to install Superuser immediately.  This will give you the ability to approve applications for root privileges.  Other good applications for security are Lookout Mobile Security and DroidWall.  Enjoy your root!

Tagged with:

It was time for me to upgrade from the Samsung Saga. It’s been nice, but the old Windows Mobile is lacking in features that the modern phones have. I’ve wanted a Droid ever since they’ve come out, but the original price was about $500 or $200 with a 2 year contract with Verizon (and then we’re back to being locked to a data plan that I have no interest in). Well now, it’s been almost 2 years since the Droid was released and people are coming to the end of their contracts. It’s about that time they usually want to upgrade their phone, which means you can find these older phones on EBay.

I picked up a used Droid for $60 shipped. It was in decent shape (no damage to the keyboard or LCD, but normal wear on the case). I purchased a 16 GB microSD card on sale from TigerDirect for $20 and a cable pack (since the auction I won didn’t come with the USB cable) for $6 on EBay which came with the USB sync cable, another wall charger, and a car charger. I used another ESN transfer service that I found on EBay for $1.99 and started using the Droid. All-in-all, I’m about $90 into the phone with 16 GB of storage, 2 wall chargers, a USB sync cable, and a car charger. For a phone that retailed brand new for about $500 2 years ago, that’s not too bad.

I have to preface this next portion with the following statement: This is my first experience owning an Android device. Prior to this point, I’ve only owned non-Smartphone cell phones, 2 Windows Mobile phones (the 6 series), and an IPod Touch. I’ve seen what Android powered devices could do, so I knew this would work well for what I needed to use it for. The difference between Windows Mobile 6 to iOS was huge, but the jump to Android is incredible. You can jailbreak an iOS device and you’ll get more freedom, but rooting an Android device with it’s own keyboard is like having a miniature, mobile computer in your pocket that you customize any way you want.

However, there are few things that make me a little uneasy about the Droid.  I’ve heard random noise about security concerns in Android, but never really read into the issues in depth.  One thing that I noticed right away is that Android doesn’t encrypt any data on the microSD card by default. That made me very reluctant to store any application data on the SD card at all. In the event your phone was stolen, anything that an android application stores on the microSD card would be accessible simply by removing the card and inserting it into a PC. That alone was reason enough to be certain nothing sensitive was stored on the microSD card.  I’ve had several discussions about this with friends and co-workers ever since I found out about this and I still feel Android should have an option to encrypt SD card data (apparently others feel the same). Windows Mobile 6 even had this feature.

After researching the encryption on the microSD card, I then started to question how the apps share data, and found articles regarding certain apps that had been caught reading data stored by other apps. I had always known there was an issue with malicious apps in the Android Market and the iTunes store, but legitimate apps stealing data from other legitimate apps? That’s not cool at all… So, this made me very picky as to what apps I was going to install. There are also ways to exploit Android to extract data. One such attack can be done using an XSS bug on an Android 2.2 device that will allow the attacker access to the SD card (video demonstration using XSSF in Metasploit).

To take the same approach that I have taken for the last few years (which is find the cheapest cell phone service that doesn’t require a dataplan) WIFI on the phone was a must and the ability to install quality offline applications (that don’t require access to the Internet).  After some research, I decided Page Plus is still the best value for the service (1200 Talk n’ Text with 100 MB of Data for $29.99 is the best and most affordable plan I’ve seen). I used Kitty Wireless to do the ESN Change (it was $1.99 on EBay).  Some apps that I found that were highly recommended are MapDroyd (which allows offline GPS), WikiDroyd (offline Wikipedia reader), and FBReader (popular free e-book reader), MoboPlayer (free video player), and Opera Web Browser for android.

Overall, my impressions of the phone itself is good.  Call quality on the Droid is about the same as the Samsung Saga (slightly better).  The accelerometer behavior during a call took a little getting used to, but easy to adapt to.  It’s very easy to turn on/off the data plan, as well as disable Auto-sync or Background data traffic of the applications.  Easy to move apps to different home screens.  My only complaint of the hardware is the keyboard.  The keyboard doesn’t quite feel right and takes a little getting used to.  The keys themselves are glued on to a press button keypad and one of the keys has already come off.  I’ve come accustomed to the raised button keyboard of the Samsung Saga, so the flat keypad is a step down in my opinion.  CNet did a nice video review for more information on the phone.

The TL;DR version of this post: So far, the Motorola Droid on Page Plus works well and I’m satisfied.  I like the Droid more than any other mobile device that I have used in the past.  I plan on doing a few posts regarding this phone and/or the Android OS as I’m getting used to all that it can do.


Tagged with:

Over the years, I have used my XBox for gaming and media center needs.  I recently sold many of my older gaming consoles because they were sitting on the shelf collecting dust.  Despite the other systems meeting the end of their shelf life in my house, my XBox was still being used.  However, it’s no longer my primary media center device.  Even still, the XBox has much potential, so I decided to keep it for my next project: My Home Arcade Machine.

This project was 2 years in the making.  I originally purchased an old beaten down solid black Tetris arcade cabinet about 2 years ago from a garage sale for $100.  The cabinet sat in my garage for a year before I was even able to begin working on it.  First, I gutted the cabinet, then refinished the wood and painted the whole thing black.  I then put all the molding pieces back on (those that didn’t need to be replaced) and purchased the additional parts I needed: LCD, Control Deck, new T-molding, and additional wood/brackets to mount everything.  All-in-all the project cost me roughly $450, with the majority of the money spent on the X-Arcade Dual Joystick and the adapter to connect the joystick to the XBox.  You can pick up an original XBox on Ebay for about $40 and a 19″ LCD will run about $100 on EBay.

The XBox component was the easiest part of this whole process.  Simply softmod the XBox, install XBMC4XBOX, and then install the emulators/games of your choosing.  I found that running MAME games made after 1991 in an emulator on the XBox to be a bit problematic.  For instance, the original Mortal Kombat echoed in the sound, Mortal Kombat 2 was very shaky, and NHL 2 on 2 Open Ice Challenge would run out of memory at the time of launch.  After some searching, I did come across a forum post that suggested turning off the sound would allow you to run the game, which wasn’t what I was looking for.  I spent countless hours playing these games in the arcade and they were the primary catalyst for me building my own MAME Arcade.  So, instead of using an emulator, I decided to run the games natively on the XBox using a known Arcade-to-XBox gaming compilation, such as Midway Treasures 1 2 or  3, Namco Museum or 50th Anniversary Edition, Capcom Classics 1 or Volume 2, or Atari Anthology.  You can find most of these titles on Ebay for $5 each.

Midway Treasures 2 has Mortal Kombat 2 and 3, which was an absolute necessity for me to keep going with the XBox.  As for NHL 2 on 2 Open Ice Challenge, Midway never made a version of that game for the XBox.  However, Midway did make a very similar series of games for the XBox called NHL Hitz (20-02, 20-03, and Pro).  Instead of 2 on 2, the game play is 3 on 3, but has a very similar arcade feel to it.  I’ve always described these games as the NBA Jam or NFL Blitz of Hockey (which by the way, both also made by Midway and ported to the XBox).

So, to review:
1.) Cheap cabinet found on Craigslist for $100 (or build your own)
2.) 19″ LCD on EBay for just under $100
3.) XBox on Ebay for $40 – Loaded with XBMC
4.) X-Arcade Dual Joystick and XBox Adapter = $160
5.) Sandpaper, Paint, Additional Supplies ~ $50

I would also recommend installing a new hard drive in the XBox (especially if you are running off the original hard drive) – Instructions here.  You can find one for about $50.  I pulled mine from an older machine that I wasn’t using anymore.  Make sure you buy an IDE drive, not SATA.

Here’s a few images of my finished cabinet:

I now have my own personal Home Arcade Machine Powered by an Original XBox running XBMC.

The next thing I would like to figure out is how to get Golden Tee working on XBMC.  Any help would be greatly appreciated!

Tagged with:

A while back, I wrote a short post linking to a wiki article about “How to Go from Xbox to Xbox Media Center in 30 Minutes”.  That was 4 years ago.  Since that time, I’ve gone through a couple different consoles and media center apps.  However, I still go back to my XBox and use XBMC quite a bit.

XBMC is still one of the most amazing media center apps that I’ve ever used.  I was a little disappointed when the XBMC team decided to discontinue support for the old XBox.  However, it didn’t take long for the XBMC 4 XBox movement to start.  In the last month, version 3.0.1 stable was released.

However, I run into a bit of an issue.  I had never installed a new Hard Drive in my XBox and I knew it was getting quite old.  So, it was time to figure out how to do this.  Luckily, it’s very simple.

To start, watch these 2 videos: How To Put A New Hard Drive In Xbox Without a Mod Chip
Pt 1:
Pt 2:

The creator does a good job showing how easy it is to make a copy of your current HD onto an ISO using XBoxHDM and then creating a new XBox Hard Drive from a burned CD made from the ISO.  I created step-by-step instructions below to complement the video:

1.) Create an xboxhdm folder with xboxhdm in it
2.) Connect to XBox via FTP and download: c\backup\eeprom.bin and put it in xboxhdm/linux/eeprom
3.) in xboxhdm/linux download C, E, and F drives from Xbox to those folders on your PC
4.) Remove the games from the Xbox folders that were copied to keep the ISO file size to a minimum (to put on a single CD).
5.) Run xboxhdm/makeiso-win –> Will create the ISO
6.) Burn the ISO to a CD – Use Lowest possible Burn speed
7.) Boot ISO on PC and make sure only the HD you want to copy to is connected to PC (disconnect other drives) –> Primary, Master Port
8.) Option 3
9.) Type: unlockhd -a     –> May say drive is already unlocked, no big deal, move along
10.) Type: reboot
11.) On next boot up, back at menu screen, just press enter
12.) Type: xboxhd
11:) Type: yes
12.) 1   –> Build a new XBox HD from scratch
–> If you have an HD over 8 GB, it will ask you if you want to create an F FATX partition (3 yes answers).
13.) yes
14.) yes
15.) yes
16.) Option 6: generate hdkeys   –> Write down hard drive key and locking password
17.) Press enter
18.) Type: 8
19.) Type: reboot
20.) Type: 3
21.) Type: lockhd -a
22.) Type: y
23.) Verifty and write down master password
24.) Shutdown PC and put the new hard drive into the Xbox and it should work

I ran into 2 issues during this process:
1.) I had an error when trying to unlock the HD stating “cannot change security status of a frozen drive”.  The fix is to have the HD plugged into the IDE at boot, but keep the power cord to the HD unplugged.  Once you boot into the first XBoxHDM menu screen, plug in the power.  Do this everytime you have to reboot.  (Forum post)
2.) I needed to rerun the softmod after installing the new HD to get back to a point where I could FTP into the XBox.  Otherwise, I was stuck with the regular XBox Dashboard and couldn’t switch to UnleashX, Evolution X, or XBMC.  To get this working:

  • Exploit the XBox again (same as what has to be done to softmod it)
  • Remove the softmod, then restart
  • Exploit again
  • Install the softmod, restart
  • Boot into evolution x and ftp XBMC files over, then restart.

I’m extremely happy with XBMC4XBOX version 3, and I’m glad this project is still moving forward after all this time.  That shows you how incredible the XBox console is and how awesome this homebrew open source application is and has evolved to overtime.


Tagged with:

This is a continuation of a Part 4 – Implementing User Account Lockout in the Customer Portal, regarding implementing account lockout in the Customer Portal.  Now, I’ll go through how to do this in the vTiger CRM application.

PLEASE NOTE: The edits were done on a system with all the previous changes that I have made in previous vTiger Customization posts.  If you haven’t made those changes to your code, then the line numbers might be off.  I tried to be as descriptive as possible as to the location of the edits, and I have used the syntax of “Around line” so that you understand that the code change line is not exact.  Code changes and statements to run in mysql are noted in BOLD.  Anything in italics is to help you understand the surrounding code.

ADDITIONAL NOTE: For some reason I was only able to get this working for quick edits in the DetailView.  When updating this field using the EditView, the field is set back to 0.  If anyone can tell me what I’m missing here, I’ll add it into the HOWTO.  Also, this feature customization will only work if you are using vTiger’s Integrated/SQL Authentication.

The strange part about this is feature is that vTiger already tracks login attempts using a session variable: $_SESSION['loginattempts'].  These attempts are logged to the Log4PHP log, but these attempts are never logged to the database.


First, we need to create the new field in the vtiger_users table:

ALTER TABLE vtiger_users ADD failed_login_attempts INT(11) DEFAULT 0;

Next, you need to let vtiger know that the field exists by adding an entry to the vtiger_field table:

insert into vtiger_field (tabid, columnname, tablename, generatedtype, uitype, fieldname, fieldlabel, readonly, presence, selected, maximumlength, sequence, block, displaytype, typeofdata, quickcreate, quickcreatesequence, info_type, masseditable, helpinfo)
select 29, ‘failed_login_attempts’, ‘vtiger_users’, 1, 7, ‘failed_login_attempts’, ‘Number of Failed Login Attempts’, 1, 2, 0, 100, 15, 77, 1, ‘I~O’, 1, NULL, ‘BAS’, 1, NULL;

Finally, the documentation suggests that entries should be added to these tables:

insert into vtiger_profile2field (profileid, tabid, fieldid, visible, readonly)
select 1, tabid, fieldid, 0, 1 from vtiger_field where columnname=’failed_login_attempts’;

insert into vtiger_def_org_field (tabid, fieldid, visible, readonly)
select tabid, fieldid, 0, 1 from vtiger_field where columnname=’failed_login_attempts’;

From what I’ve tested, the inserts to vtiger_profile2field and vtiger_def_org_field aren’t necessary, but the documentation on the vtiger website suggests they should be done.

vTiger CRM Code Updates

In vtigercrm/modules/Users/Users.php:

Around line 394, update the query statement:
$this->log->debug(“Using integrated/SQL authentication”);
$encrypted_password = $this->encrypt_password($user_password);
$query = “SELECT * from $this->table_name where user_name=? AND user_password=? AND COALESCE(failed_login_attempts,0)<5″;
$result = $this->db->requirePsSingleResult($query, array($usr_name, $encrypted_password), false);

Around line 438, update the query statement in the if block:
$this->log->warn(“User authentication for $usr_name failed”);
// Increment number of failed login attempts
$query = “UPDATE $this->table_name SET failed_login_attempts=COALESCE(failed_login_attempts,0)+1 where user_name=?”;
$this->db->requirePsSingleResult($query, array($this->column_fields["user_name"]), false);
return null;

Around line 470, add this code near the end of the function:
if ($row['status'] != “Inactive”) $this->authenticated = true;

// Reset number of failed logins
if ($this->authenticated) {
// Increment number of failed login attempts
$query = “UPDATE $this->table_name SET failed_login_attempts=0 where user_name=?”;
$this->db->requirePsSingleResult($query, array($this->column_fields["user_name"]), false);

return $this;

After those modifications, you should have User Account Lockout Implemented on vTiger CRM.

1.) Creating New Fields in Existing Modules
2.) Implementing Access Controls


I submitted the updates to the Trac site for vTiger as diff updates to the vtigercrm 5.2.1 code, which might be easier to use to update the code.

The current version of the vTiger Customer Portal (5.2.0) is susceptible to a brute force attack in that it doesn’t enforce strong passwords of Customer Portal users and that there is no Account Lockout feature when too many invalid login attempts are made on an account. In a previous post, I showed how you can enforce strong passwords in the Customer Portal.

In this post, I will demonstrate how you can implement Customer Portal User Account Lockout. This is very easy to do. There are only 2 changes that need to be made to implement this feature:
1.) Create a database field to record the number of failed login attempts that a portal user makes
2.) Update the SOAP function to authenticate a user

1.) First, create the new field. Login to vtigerCRM as admin. Go to Settings –> Module Manager. Click the edit button to the right of Contacts (it looks like a hammer). Click Layout Editor. In the Customer Portal Information block, add a new number field called “Number of Failed Attempts” (you can make it with a Length of 3 and 0 Decimal Places).

Now, you need to find out the name of the database field that you just created in the vtiger CRM Module Manager (I still haven’t found the most efficient way to do this, so just login to mysql (mysql -u username -D vtigercrm520 -p) and run this command: describe vtiger_contactscf;) For the sake of this example, we will use the field name of vtiger_contactscf.cf_674 (NOTE: Your field name might be different. Make sure to replace the cf_674 field in the code below with the new field that you created in your implementation of vtiger CRM). Once you have the name of the new field, we can implement the change in the SOAP interface.

2.) Make the changes to vtigercrm/soap/customerportal.php. These 3 changes need to be made to the authenticate_user function:

a.) On line 966, update the $sql query:

$sql = “select id, user_name, user_password,last_login_time, support_start_date, support_end_date, COALESCE(vtiger_contactscf.cf_674,0) as failed_attempts from vtiger_portalinfo inner join vtiger_customerdetails on inner join vtiger_crmentity on inner join vtiger_contactscf on where vtiger_crmentity.deleted=0 and user_name=? and user_password = ? and isactive=1 and vtiger_customerdetails.portal=1 and vtiger_customerdetails.support_end_date >= ?”;

b.) On line 974, update the elsif:

elseif($num_rows <= 0)
// Increment number of failed attempts
if ($login == ‘true’) {
$sql = “update vtiger_contactscf inner join vtiger_portalinfo on set cf_674=COALESCE(vtiger_contactscf.cf_674,0)+1 where user_name=?”;
$adb->pquery($sql, array($username));
return $err[1];//No user
else {
$failed_login_attempts = $adb->query_result($result,0,’failed_attempts’);
if ($failed_login_attempts >= 5)
return $err[1];

c.) Just before the function return, add this code:

// If authentication is sucessful, reset number of failed attempts
$sql = “update vtiger_contactscf set cf_674=0 where contactid = ?”;
$adb->pquery($sql, array($customerid));

That’s it! You now have Account Lockout enabled to Customer Portal user accounts. After 5 failed login attempts, someone with access to the vtiger CRM system will need to reset the “Number of Failed Attempts” value in the Contact’s record back to a lower number than 5 for the user to be able to login to the Customer Portal again.

Tagged with:

In a previous post, I outlined how to segment each port of an ASUS RT-N16. Now, I’ll go over the details of implementing uPnP on one or more segments.

First off, autobot on the DD-WRT forums posted the code and binary for MiniUPnPd (link).  The script and binary provided are great.  However, the startup script downloads the latest version of the shell script and the binary via HTTP from the google code site.  Although these scripts offer a very easy way to get uPnP up and running quickly, this is a BAD idea.  For one, if you are going to do something like this, use HTTPS.  Second of all, it’s not a very good idea to allow a script that you have no control over the content of, to be copied and executed by your router on boot every time your router is restarted.  Instead, if you have some free space on the router, it’s probably better to store static copies of the scripts in the JFFS (the Journaling Flash File System).

Here are the steps to get this working:

1.) Install the BIG build. In order to enable JFFS, I had to install the BIG build (also known as mega).  The mini build had the option for JFFS support, but when I enabled it I still couldn’t write files to /jffs/.  So, I upgraded from Mini to Mega.  First I installed Mini, then I downloaded the binary for Mega.  I updated Mega by going to Administration –> Firmware Upgrade.  Select the binary for BIG and click Upgrade.  Upgrade may take 5 min…

2.) Enable jffs: In the web interface.  Go to Administration –> Management.  Find jffs Support and select Enable.  Click Save.  Apply Settings.  Now you can store files to the /jffs/ directory on the router.

3.) Verify uPnP is disabled in DD-WRT.  Go to NAT/QoS –> UPnP.  Make sure UPnP Service is set to Disable.

4.) Upload the miniunpd files to the router. Telnet/SSH to the router.  Change directory to /jffs/.  Now, download the miniupnp files, here and here.  (NOTE: The shell script and configuration file are not the originals – I made updates to them – Specifically, I reference the config file in the shell script which has uPNP turned on for the .11 and .13 networks, turned it off for everything else, and a few other small updates.  The originals can be found here and here.)  You can follow the directions below to copy down autobot’s files, and you can override with my .sh and .conf files if you would like (whatever you want to do).

mkdir /jffs/miniupnpd
wget -O /jffs/miniupnpd/
wget -O /jffs/miniupnpd/miniupnpd.conf
wget -O /jffs/miniupnpd/miniupnpd.gz

The part that allows you to control which segment is allowed to use uPnP is in the .conf file.  Specifically, these lines allow/deny access to the specified segments:

allow 1024-65535 1024-65535
allow 1024-65535 1024-65535
deny 0-65535 0-65535
deny 0-65535 0-65535
deny 0-65535 0-65535

It’s recommended to add this line at the end of the rules:

deny 0-65535 0-65535

NOTE: In the configuration file, I disable uPnP for the .12 and .14 networks (you can enable/disable uPnP for whatever networks you want).

5.) Edit the startup script of the router to start miniunpd on boot. In the DD-WRT web interface, go to Administration –> Commands.  Under the Startup section, click Edit.  At the end of the startup commands, add the following:

sleep 10
sh /jffs/miniupnpd/

Click Save Startup.

When you restart the router, MiniUPnPd should be running for the networks that you specified in the configuration file.


1.) MiniUPnPd Web Installer – Available for Testing

2.) Adventures with DD-WRT Part 7: Installing MiniUPnP

3.) How to get UPNP working on DD-WRT

Tagged with:

DD-WRT is really amazing in all that it can do.  I have grown much more fond of it overtime.  Recently, I decided that I wanted to completely segment my home network.  I wanted to have multiple networks (some trusted, others completely untrusted) that could be configured through a single device.  At first, one would assume that this might take multiple firewalls to block incoming traffic from another firewall.  DD-WRT can do it in one device segmented by port.

Since I decided it was time to give my home network and overhaul, I decided that it was time to upgrade to gigabit ethernet as well.  I started looking for a device that would do all of this and could handle all the rules and traffic that I could possibly throw at it.  I came across the ASUS RT-N16: Wireless N Router with a 4 port gigabit switch, 32 MB ROM, 128 MB RAM, and…  installing DD-WRT is a breeze (instructions).  NOTE: This howto uses DD-WRT v24-sp2 mini

Now, it took me a couple tries to get the segmentation working right.  I wanted to switch the WAN to vlan0, but everytime I tried doing that, something went wrong, so I ended up keeping it on vlan2 (which is where it was by default).  Also, I decided to keep the trusted network on vlan1 and the rest of the networks on vlan12, vlan13, and vlan14 respectively.  The wireless adapter is eth1.  Now, you need to discover which port numbers in DD-WRT correspond to which “physical” port numbers on the router itself.  Here is the mapping:

DD-WRT = Physical Port
0 = WAN
1 = 4
2 = 3
3 = 2
4 = 1

This actually corresponds to the order that you see the ports if looking at the back of the router and reading the ports from left to right.
Anyway, now that you have this mapping, you are ready to begin setting up your VLANs.

1.) Connect your computer to Physical LAN port 1 on the router.  Log into the router via telnet and run these commands:

nvram set vlan0ports=”0 8″
nvram set vlan1ports=”4 8*”
nvram set vlan2ports=”3 8*”
nvram set vlan3ports=”2 8*”
nvram set vlan4ports=”1 8*”

nvram set rc_startup=’

ifconfig vlan2 netmask
ifconfig vlan3 netmask
ifconfig vlan4 netmask

ifconfig vlan2 up
ifconfig vlan3 up
ifconfig vlan4 up

nvram set rc_firewall=’
# Accept traffic into vlan12
iptables -I INPUT -i vlan12 -j ACCEPT
# Allow traffic outbound to forward from vlan12 to vlan2 (WAN)
iptables -I FORWARD -i vlan12 -o vlan2 -m state –state NEW -j ACCEPT
# Disallow access to the router on vlan12 through the typical ports for management (telnet,ftp,ssh,http,https)
iptables -I INPUT -i vlan12 -p tcp -m multiport –dports 21,22,23,80,443 -j DROP
# Disallow anything on .12 (vlan12) to communicate to the other networks
iptables -I INPUT -s -d -j DROP
iptables -I INPUT -s -d -j DROP
iptables -I INPUT -s -d -j DROP
iptables -I INPUT -s -d -j DROP
# Disallow anything on the bridge interface to communicate to vlan12
iptables -I FORWARD -i br0 -o vlan12 -j logdrop

iptables -I INPUT -i vlan13 -j ACCEPT
iptables -I FORWARD -i vlan13 -o vlan2 -m state –state NEW -j ACCEPT
iptables -I INPUT -i vlan13 -p tcp -m multiport –dports 21,22,23,80,443 -j DROP
iptables -I INPUT -s -d -j DROP
iptables -I INPUT -s -d -j DROP
iptables -I INPUT -s -d -j DROP
iptables -I INPUT -s -d -j DROP
iptables -I FORWARD -i br0 -o vlan13 -j logdrop

iptables -I INPUT -i vlan14 -j ACCEPT
iptables -I FORWARD -i vlan14 -o vlan2 -m state –state NEW -j ACCEPT
iptables -I INPUT -i vlan14 -p tcp -m multiport –dports 21,22,23,80,443 -j DROP
iptables -I INPUT -s -d -j DROP
iptables -I INPUT -s -d -j DROP
iptables -I INPUT -s -d -j DROP
iptables -I INPUT -s -d -j DROP
iptables -I FORWARD -i br0 -o vlan14 -j logdrop

nvram commit

2.) Login to the web interface for DD-WRT.  Go to Setup –>VLANs.  Setup the ports in this manner:
VLAN 1 = 1 checked, LAN
VLAN 2 = W checked, None
VLAN 12 = 2 checked, None
VLAN 13 = 3 checked, None
VLAN 14 = 4 checked, None

Click Save.

3.) Go to Setup –> Networking.  Verify WAN port set to vlan2.

4.) Go to Services –> Services.  Copy the below in “Additional DNSMasq Options”:


Click Save.

5.) Go to Setup –> Basic Setup

Change Local IP Address to

Click Save.  Apply the Settings (this should reboot the router).

How To Setup Unbridged Wireless

This was a bit tricky.  I followed several HOWTOs until I found one that actually worked.  Here’s what I did:

1.) In the Web Interface, go to Wireless –> Basic Settings.  Make sure Network Configuration is set to Bridged.

2.) Go to Setup –> VLANs.  Make sure Wireless is set to LAN.

3.) Setup a new Bridge for Wireless.  Go to Setup –> Networking.  Add a Bridge called br1.  IP Address:, Subnet Mask: 255.255.255.
Click Save and Apply Settings.

Assign the new bridge br1 to interface eth1.  Apply Settings.

4.) Go to Services –> Services.

Add the following under DNSMasq to setup DHCP:


Save and Apply Settings.

5.) Now you need to setup the iptables rules to prevent it from talking to the other networks.

# Wireless
iptables -I INPUT -i br1 -p tcp -m multiport –dports 21,22,23,80,443 -j DROP
iptables -I INPUT -s -d -j DROP
iptables -I INPUT -s -d -j DROP
iptables -I INPUT -s -d -j DROP
iptables -I INPUT -s -d -j DROP

Now you have a router that segments each port (and WIFI) into it’s own network.  Enjoy!

NOTES: I used A LOT of resources to construct this HOWTO, most of which were on DD-WRT’s Wiki (which is just an absolutely awesome site with almost anything you could want to know about DD-WRT).  However, A LOT of this was still trial by fire.


1.) V24: WLAN separate from LAN, with independent DHCP
2.) Multiple WLANs
3.) VLAN Detached Networks (Separate Networks With Internet)
4.) Iptables command – Deny access to a specific Subnet
5.) Preventing Brute Force Attacks
6.) DD-WRT – Setting up a separate / isolated VLAN on Port 4 with DHCP
7.) Routers that will and won’t support VLAN

Tagged with:

This is a continuation from Part 2 – Enforcing strong passwords in vTiger.

I submitted the updates to the Trac site for vTiger as diff updates to the 5.2.0 code, which might be easier to use to update the code.

Implementing the enforcement of strong passwords in the vTiger Customer Portal is easy to do. Again, I’ll divide this up into 2 sections, the Front end (Javascript) code and the Back end (PHP) code:

1.) Customer Portal Front end password enforcement (Customer Portal Javascript)
2.) Customer Portal Back end password enforcement (Customer Portal PHP code)

1.) Customer Portal Front end password enforcement to vtiger/customerportal/MySettings.php –> F/E
Line: 134

-confirmpw = trim(form.confirm_password.value);

var passwordCheckRegex = new RegExp(“^(?=.{7,})(((?=.*[A-Z])(?=.*[a-z]))|((?=.*[A-Z])(?=.*[0-9]))|((?=.*[a-z])(?=.*[0-9]))).*$”, “g”);

-if(oldpw == ”)

Line 149:

else if (passwordCheckRegex.test(trim(newpw)) == false) {
alert(“Password not strong enough. Please enter a password 8 characters or more, 1 upper case letter, 1 lower case letter and 1 number”);
return false;

2.) Customer Portal Back end password enforecment in vtigercrm/customerportal/HelpDesk/Utils.php –> B/E
Line: 115

-if(strcasecmp($newpw,$confirmpw) == 0)

if (preg_match(‘/^(?=.{7,})(((?=.*[A-Z])(?=.*[a-z]))|((?=.*[A-Z])(?=.*[0-9]))|((?=.*[a-z])(?=.*[0-9]))).*$/’, $newpw, $matches) >= 1) {

-$customerid = $result[0]['id'];
-// $customerid = $_SESSION['customer_id'];
-$sessionid = $_SESSION['customer_sessionid'];


$errormsg .= ‘Password not strong enough. Please enter a password 8 characters or more, 1 upper case letter, 1 lower case letter and 1 number’;

-$errormsg .= getTranslatedString(‘MSG_ENTER_NEW_PASSWORDS_SAME’);

NOTE: As I stated in the last post, I did not create this regex. I used the medium regex created found by Doug in his post found here.

Now, you can rest a little better knowing that your customers are using strong passwords on your Customer Portal site. I hope you found this helpful!

Resources: Check Password Strength with Javascript and Regular Expressions


UPDATE 10/5/2010: I submitted the updates to the Trac site for vTiger as diff updates to the 5.2.0 RC code, which might be easier to use to update the code.

One of the things that really bothers me is that there are no built-in password restrictions for users in vTiger. That means if a user wants to set his/her password to the number 1, they can do that. That leaves the user’s account VERY vulnerable to attack.

It’s very easy to implement enforcement of strong passwords in vTiger. There are 2 places we need to implement this: in Javascript and in the actual PHP code. By implementing this in Javascript, the user is alerted immediately that their password doesn’t meet the password requirements without requiring a post to the server. By implementing this in the actual PHP code, we can ensure that the user didn’t try to bypass the Javascript (for instance, they may have Javascript turned off in their browser).

In addition to making changes in Javascript and the PHP code, we need to make these changes to the Customer Portal as well. Since the Customer Portal is considered a separate module, I’ll cover how to enforce strong passwords in the Customer portal in another post. We’ll divide this update into 2 parts:

1.) vtigercrm Front end password enforcement (vtigercrm Javascript)
2.) vtigercrm Back end password enforcement (vtigercrm PHP code)

I’ll iterate through each section and outline the changes to make:

1.) vtigercrm Front end password enforcement – update to verify_data function in vtigercrm/modules/Users/Forms.php
Line: 163

var passwordCheckRegex = new RegExp(“^(?=.{7,})(((?=.*[A-Z])(?=.*[a-z]))|((?=.*[A-Z])(?=.*[0-9]))|((?=.*[a-z])(?=.*[0-9]))).*$”, “g”);
if (passwordCheckRegex.test(trim(form.user_password.value)) == false) {
isError = true;
errorMessage += ‘Password not strong enough. Please enter a password 8 characters or more, 1 upper case letter, 1 lower case letter and 1 number’;
oField_miss = form.user_password;

Line: 214

-if(trim(form.user_password.value) != trim(form.confirm_password.value))
-set_fieldfocus(“The password does’t match”,form.user_password);
-return false;

var passwordCheckRegex = new RegExp(“^(?=.{7,})(((?=.*[A-Z])(?=.*[a-z]))|((?=.*[A-Z])(?=.*[0-9]))|((?=.*[a-z])(?=.*[0-9]))).*$”, “g”);
if (
.test(trim(form.user_password.value)) == false) {
set_fieldfocus(‘Password not strong enough. Please enter a password 8 characters or more, 1 upper case letter, 1 lower case letter and 1 number’, form.user_password);
return false;


In file: vtigercrm/modules/Users/ChangePassword.php at Line 40 and Line 56
->function set_password(form) {
var passwordCheckRegex = new RegExp(“^(?=.{7,})(((?=.*[A-Z])(?=.*[a-z]))|((?=.*[A-Z])(?=.*[0-9]))|((?=.*[a-z])(?=.*[0-9]))).*$”, “g”);

if (passwordCheckRegex.test(trim(form.new_password.value)) == false) {
alert(‘Password not strong enough. Please enter a password 8 characters or more, 1 upper case letter, 1 lower case letter and 1 number’);
return false;

2.) vtigercrm Back end password enforcement in file vtigercrm/modules/Users/Users.php:
Line: 526

-if( !isset($new_password) || $new_password == “”) {
-$this->error_string = $mod_strings['ERR_PASSWORD_CHANGE_FAILED_1'].$user_name.$mod_strings['ERR_PASSWORD_CHANGE_FAILED_2'];
-return false;

if (!(preg_match(‘/^(?=.{7,})(((?=.*[A-Z])(?=.*[a-z]))|((?=.*[A-Z])(?=.*[0-9]))|((?=.*[a-z])(?=.*[0-9]))).*$/’, $new_password, $matches) >= 1)) {
$this->error_string = ‘Password not strong enough. Please enter a password 8 characters or more, 1 upper case letter, 1 lower case letter and 1 number’;
return false;

-$encrypted_password = $this->encrypt_password($user_password);

NOTE: I did not create this regex. I used the medium regex created by Doug in his post found here.

And there you have it. Next post, how to enforce strong passwords in the customer portal module.

Resources: Check Password Strength with Javascript and Regular Expressions

Set your Twitter account name in your settings to use the TwitterBar Section.