Wednesday, August 24, 2011

I Was Called an Asshole by a TeleMarketer From Rapid7.

I work in IT (obviously) and we get LOTS of calls from people trying to sell us stuff.  We have told the gatekeeper (our receptionist) that she can tell any and all of them we do not need their services and please stop calling, and that if we do need their services we will seek them out.  Frequently a sales person will call multiple times before getting the hint that our gatekeeper is not going to open the door to the IT department.  She's very good at that.

Sales calls are a part of life, it's how a lot of business gets done.  Good sales people will try a couple times and eventually get the hint that the person they are calling truly isn't interested and will move on to the next record.  It's not uncommon to have to deal with rude receptionists (ours isn't) or irritated people on the other end of the line, it's also part of the job, so it's not necessarily a fun job to have.  However, it is not part of the job to call people names when they don't give you the opportunity to give your sales pitch.  It's your job to move on. 

Unfortunately one pesky agent from Rapid7 apparently doesn't know this, calling for both myself and my boss  several times over the course of a week, and would not take no for an answer.  Lauren was certain that because our  receptionist doesn't know what they do she can't possibly make the decision that we don't need her services.  Our very polite receptionist asked that next time she called I PLEASE take the call so I can tell them we don't need their services.  I did.  This is the story of that call.

8/24/2011, 1:05 PM:
I take the call and Lauren is very chipper and polite, attempting to sound like I'm her best friend (a decent sales tactic, it's much more interesting than monotone).  I immediately go in to my spiel about how we don't need whatever it is that they are selling, and that I would like her to please stop calling as she is annoying our receptionist.  She quickly became defensive and astounded that I would "blow her off" without even knowing who she was or why she was calling and that I would be sorry when in a month or two I needed to do a risk assessment (I doubt I will) and I had blown her off.  I informed her that was exactly what I was doing, and if we needed their services in the future I would happily call her (I won't now), and she would remember me and be happy I called.  She told me that she wouldn't be happy because she doesn't like working with assholes or poor people.  Seriously.  That's exactly what she said.

I said I can definitely be an a-hole sometimes but I have been polite and simply asked you to stop calling, if I was an a-hole I would have simply hung up on you.  At that point she hung up on me.  How rude.

I can't believe a telemarketer who was trying to sell me something called me an a-hole while I was being polite.  

NOW this blog post is me being what she called me. As was the email I sent to every email address listed on their website detailing this call.


Update:
Here is the reply I received from Rapid7

Hello Andrew,

Thank you very much for taking the time to get in touch with us so that we can investigate this issue. I can assure you it is certainly NOT our practice to call prospects names nor insult them. 

I’ll speak with the head of our Sales team right away to look into this. 

I can certainly understand the frustration that you’re feeling now but do hope that you’ll give us another chance in the future should you need Vulnerability Management solutions. 


Thanks,
Catherine

Thursday, August 4, 2011

CloudTC Android Based Executive SIP Phone Unveiling/Review

Update: Panasonic has released their KX-UT670 which is a much better option than the CloudTC phone.  You can read about it here: http://www.andrewparisio.com/2012/05/panasonic-ut670-review.html

In October 2010 CloudTC was showing off their fancy new Glass 1000 Phone at Astricon.  It's a beautiful device with huge potential in the SIP/Asterisk world.  We signed up to get a pair of development units which ended up shipping a little later than they had hoped for but it wasn't the end of the world.  Check out the picture of this thing, it looks quite impressive.



Phone Construction:
The phone is well built, it has a heavy base so it doesn't tip over when you press on it, however in order to press the home button I've found myself holding the back side of the phone with my fingers while pressing the button with my thumb as it requires quite a bit of pressure and sometimes can cause the phone to slide across my desk.  The handset is very light, which some people consider cheap feeling but that doesn't both me.  The handset that shipped with the device tends to fall off of the phone because the notch isn't deep enough, CloudTC said they will be shipping new handsets out that solve this problem as well as some call quality problems (which I honestly haven't noticed).  For an Executive SIP Phone I think this device is fairly well designed, although a case that is more "sexy" might add more appeal for picky executives.   

Phone Configuration:
Configuration of the Glass phone is very simple, the IP address is displayed in the top right hand corner so you simply navigate to that IP in your web browser and configure the SIP settings from there, the default username and password are both admin.  I had mine up and running in a couple minutes.


Phone Features:
Anyway, the device is fairly impressive on paper.  Android 2.1, a 1024x600 9?"  touch screen (not capacitive), PoE (Power Over Ethernet), Bluetooth connectivity, a quality speakerphone and a fairly well designed case.  I quickly plugged it in to my PoE switch and it didn't work.  As it turns out, the PoE feature was removed because  of issues sourcing parts, I guess they should update their documentation page saying the device has PoE.  Oh well, I plugged in the AC adapter and fired the thing up.  The first thing I did was install angry birds on it, which as you can imagine is pretty fun on a giant screen like this.  Without multitouch support you can't zoom in or out, but that doesn't really matter as this isn't an angry birds phone, it's an executive SIP phone.


I grabbed my bluetooth headset and went to connect it to the phone, but there is no way to pair a bluetooth device unless you've used android before and know how to create a shortcut.  I simply tapped and held on the homepage, added a shortcut to bluetooth and managed to pair my device.  The unfortunate part is while it may have bluetooth connectivity apparently it doesn't use it for anything.

Using the Phone as a Phone:
As a SIP phone the device needs to work well as an actual phone, not just be a pretty toy.  I've had a few more dropped calls than I normally experience, but the speakerphone on the device is pretty good on my end although I haven't been on the other end of one of these I haven't had any complaints.  Dialing on the keypad is simple although the dialer tries to format the phone number with parenthesis which is a little bit awkward.  If I dial my extension which is 1593 the phone will display "1 (593" expecting me to dial the next 7 digits of an 11 digit US based phone number.  Currently there is no way to tell the phone what the allowed dial patterns are, if that were added they would probably be able to better format phone numbers.  Hopefully this gets added in the future.


Bug List
  • CallerID does not display the name of the caller, only the number
  • If you hold down the back button for more than 2 seconds you get an overlay of the touchpad driver
    • Fixed in build 1768 (changed to 5 seconds)
  • The phone does not support auto-answer so you can't do intercom calls or callcenter work
  • Google Maps runs out of memory if you use it, i only opened it to test but it quickly crashed
    • As of build 2009 it works for a minute but with the traffic layer on after scrolling around a couple times it says low on memory and turns off the traffic layer, then the entire phone hard locks
  • If you pull down the android notification window you are unable to slide it back up
    • Fixed in build 1768
  • Inbound calls will be rejected if they come from the same number as the phone.  If i call 1593 from another device with the callerid of 1593 it will reject the call
  • The phone dialer is clunky, and the formatting of numbers is very awkward
    • Formatting is fixed, redial added in build 2009
  • The volume controls don't provide a test-tone so you have no idea how loud 10 is until you make a test call
  • The PC Connector software which is supposed to sync your contacts from outlook is broken and won't connect -- they said they don't support this, but it's the only way to get contacts in to your phone from exchange
  • The phone lacks a DND mode
    • Fixed in build 1768
  • The phone has dropped several calls or hung up during a call :(
  • Bluetooth doesn't work
  • There is very little documentation

Final Thoughts:
CloudTC has built a beautiful phone but has left a few things to be desired in the execution.  As a new small company I'm hoping they work out the kinks and get this thing moving but they don't seem all that quick to help.  I've been an early adopter before and in most cases companies are generally very appreciative of the support they get and provide early adopters with direct access to developers, generally taking feedback and incorporating it while providing users what they need to accomplish their goals in a give and take relationship.  In fact I've gotten free devices, free software, and features I needed from companies before while helping them introduce new products to market.  I'm not sure who else is developing for this device but I'm not going to continue investing my time or energy until the kinks are worked out.  

For a $600 executive SIP phone this device comes up short.  For an Executive that just wants to make phone calls the device is sufficient, but much more advanced use and I think the device is not yet ready for prime time.

Monday, July 11, 2011

Our (Brief) Foray into a Brother HL-2280DW All In One Laser Printer

Update at bottom (7/12/2011)
The Bad:
Can't scan multiple pages in to a single document
Wireless is not so easy to configure (I'm in IT).
Drivers won't be automatically detected (It's 2011 guys)

The Good:
It prints quickly
It scans (one page) quickly, with decent image quality.


Review:

We have been printing and scanning quite a bit so decided we would get an AIO.  We wanted a laser printer as an ink toner cartridge that lasts 500 pages won't go far with 30-40 page documents.  That said we spent quite a bit of time looking around and we found the Brother HL-2280 Printer was a small and inexpensive device which takes a Brother TN-450 toner cartridge that provides a decent cost per page.  My girlfriend went to Staples to play with and purchase the said printer and the cashier, the clerk informed her that the starter toner in the printer would only print 20 (twenty) pages before running out, and therefore she should purchase a new toner to go with it; he offered to sell her a TN-420.  Really?  Lying Thieves, thankfully she wasn't suckered in by this gimmick.  For reference, the printer comes with a TN-420 toner cartridge which according to staples.com prints 1,200 pages.  I can only assume that the pimply geek with huge gauge holes in his ears was flat out lying in order to get her to purchase a toner cartridge and improve his sales attach rate.  Also, the two year warranty is only 29.99.  Thanks, we'll pass. I hope it dies before two years is up so it can fill a dumpster somewhere.

Step 1) Plug in, configure wifi (Fail #1)
With the printer at home I plug it in, and turn it on.  Open the menu, go to wifi and use the wifi protected setup menu, which i've admittedly never used.  I choose the option where it gives me a code that i type in to the router, and then the devices pair.  60 seconds later my belkin router says device connected successfully, and the printer spits out a page saying failed.  I tried a couple variations of this and eventually gave up.  Ultimately I connected to the printer via an ethernet cable, connected to the web interface with the default username of admin and the default password of password and managed to configure the wireless from there.

Step 2) Connect to computer (Fail #2)
I used the add a printer wizard in Windows 7 and to my delight it was quickly detected.  Except the printer driver wasn't found.  I went to the brother website and download the printer driver, installed it via computer management and I'm off to the races!

Step 3) Print a document (The only successful step)
It prints. Oh, and it can print on both sides / duplex perfectly.

Step 4) Scan a document (Fail #3) (Update below)
I press the scan button expecting the scan to email function similar to other brother AIO's I've used.  It says check connection.  This device can only perform the scanning functions through the brother software.  No problem I say! I download the 130MB software, install it (reboot required... ugh it's 2011), and scan a document.  All of the defaults scan to JPG, including scan to email or file.  I change it to default to PDF and go to scan my document.  As it turns out, this brother All In One HL-2280DW IS NOT CAPABLE of scanning multiple pages in to a single document.  Say you want to scan and email a 2 page document, you will need to scan it in to two separate files and email them separately.  The scanner we had some 12 or 15 years ago was capable of this simple functionality.  Press scan, it scans the document, asks you if there are any more pages, and either scans the next page or finishes with the file.

Step 5) Return for full refund.
Reason stated on return claim: defective.




My Backstory:
I have installed and used multiple brother all in one laser devices and figured I'd give them a shot since at the budget end their cost per page is far lower than the competing HP model (1.7c/page vs 5c/page).  I have no previous hatred of brother until this new device was purchased (and about to become returned).




UPDATE: 
It turns out it is possible to scan multiple pages. The preferences menu doesn't show the option, but if you right click on the email or file button for example, and go to settings you get almost the exact same menu you find under preferences, but it has a checkbox for manual scan. It does work. The downside is you must return to your computer to press the next page button, and the software on the computer effectively does a new scan job and stitches the two together. This is clearly a piece of equipment meant for scanning one page things, and the software isn't well designed (why does the checkbox only show up on right click -> settings, instead of the main preferences tab you get?

Thursday, July 7, 2011

Embedding a User Editable Google Maps and Street View Control in a Website

We recently added a feature allowing our users to show the Google Street View of their property on our website and there wasn't a lot of documentation about how to do it.  Ideally we wanted to be able to display the street view of a real estate listing so prospective buyers could get a better feel for the property and the surrounding area, and it seemed like a solveable problem.

The final solution ended up looking like this:

In order to accomplish this we needed to do several things.  First, we already know the address of the property that is being entered because as a real estate listing site that is something users enter with their listing info.  Therefore we simply need to use the google maps and google street view API to display the map and street view version to our users so they can confirm the location and angle of the view.  Once they have done this we store the POV information and the location of the property (in case the google approximation is incorrect) in our database to ensure we display the correct info.

Step 1) Display the approximate location for the street view and map controls and allow the user to adjust the view to their liking

[code]
var map1;
var panoramaOptions;
var myPano;
var point;
var point1;
var marker1;

/*********************************************************/
//Use the validate form code to set hidden textboxes to the values
//from the streetview Pano, so when the form gets submitted the
//values get passed to the server to be saved
/*********************************************************/
function validateForm(){
this.document.getElementById('pitch').value = myPano.getPov().pitch;
this.document.getElementById('heading').value = myPano.getPov().heading;
this.document.getElementById('svzoom').value = myPano.getPov().zoom;
this.document.getElementById('sv_latitude').value = myPano.getPosition().lat();
this.document.getElementById('sv_longitude').value = myPano.getPosition().lng();
this.document.getElementById('latitude').value = map.getPosition().lat();
this.document.getElementById('longitude').value = map.getPosition().lng();
return true;
}

function load() {
//set the point for the panoramic
//at this point we don't know the POV info so we set them all
//to 0, the user will have to adjust the POV and we will save
//that information
point = new google.maps.LatLng(66.6666, 66.6666);
panoramaOptions =
{
position:point,
pov: {
heading: 0,
pitch:0,
zoom:0
}
};
/*********************************************************/
//use a div with elementid pano to display the streetview panorama
/*********************************************************/
myPano = new google.maps.StreetViewPanorama(document.getElementById("pano"), panoramaOptions);
myPano.setVisible(true);


var sv = new google.maps.StreetViewService();
var availability_cb = function(data, status) {
/*********************************************************/
//if the streetview service can't display teh location (due to lack of data)
//then we use a bunch of hidden fields to display an error message
//apologizing for the inability to use streetview
/*********************************************************/
if (status !== 'OK')
{
document.getElementById('sv_enabled').checked = true;
document.getElementById('pano').style.display='none';
document.getElementById('pano').style.visibility='hidden';
document.getElementById('panotext').style.display='none';
document.getElementById('panotext').style.visibility='hidden';
document.getElementById('panoerror').style.display='';
document.getElementById('panoerror').style.visibility='';
}
/*********************************************************/
//show the panoramic
/*********************************************************/
else
{
myPano.setVisible(true);
}
}

sv.getPanoramaByLocation(myPano.getPosition(),50,availability_cb);

/*********************************************************/
//this code displays the normal streetview map and allows
//the user to drag the pushpin to set the proper location
//in the event the google provided position isn't quite accurate
//this map gets put in a div with the id map
/*********************************************************/
map1 = new google.maps.Map(document.getElementById("map"),
{
center: new google.maps.LatLng(66.6666, 66.6666),
zoom: 15,
mapTypeId: 'roadmap'
});

point1 = new google.maps.LatLng(
parseFloat(66.6666),
parseFloat(66.6666));

marker1 = new google.maps.Marker({
map: map1,
position: point1,
draggable: true
});
}


[/code]
All of the preceding code creates the following layout in the website:


Step 2) We store the information from the streetview and normal map in our database, that way when we display the listing to users they get the previously-set location.

Step 3) We display the street view control and the normal roadmap view on our site.
[code]
var map1;
var panoramaOptions;
var myPano;
var point;


function load() {
/*********************************************************/
//Set up the street view position
/*********************************************************/
point = new google.maps.LatLng(66.6666, 66.6666);
panoramaOptions =
{
position:point,
pov: {
heading: 61.4137, //This is the custom POV that was set
pitch:9.02999, //by the user
zoom:0
}
};

/*********************************************************/
//use the same divs as before, pano for streetview and map
//for the roadmap.
/*********************************************************/
myPano = new google.maps.StreetViewPanorama(document.getElementById("pano"), panoramaOptions);
myPano.setVisible(true);




/*********************************************************/
//set up the roadmap
/*********************************************************/
map1 = new google.maps.Map(document.getElementById("map"), {
center: new google.maps.LatLng(66.6666, 66.6666),
zoom: 15,
mapTypeId: 'roadmap'
});
var point1 = new google.maps.LatLng(
parseFloat(66.6666),
parseFloat(66.6666));

var marker1 = new google.maps.Marker({
map: map1,
position: point1
});

}

[/code]

Wrap Up
And once again this creates the final picture:
I've left out some things like storing the POV info in my database as well as how to convert an address in to a Lat/Lng via the google maps API so you'll have to read the API's to figure out how to do that.  This should help you a bit with the street view functionality :)
If you'd like to see it in action this code is what currently drives the street view and property map functionality of all the Commercial Real Estate Listings at www.cimls.com 

Wednesday, June 29, 2011

Asterisk Directory Application Crash With Asterisk Realtime in 1.6.2

I recently discovered that asterisk-addons-1.6.2.3 has a bug in res_config_mysql that causes asterisk to segfault if you send a user to the Directory() app while using realtime asterisk for voicemail.  This bug is fixed in the asterisk-addons branch of 1.6.2 so be sure to use the latest res_config_mysql.c if you are using asterisk-addons-1.6.2.3.  The SVN is available here: http://svn.digium.com/svn/asterisk-addons/branches/1.6.2/

I spent a fair amount of time tracing down this crash before attempting to use the latest version out of SVN and discovered that this crash had been patched about a month ago.  I guess the moral of the story is to always test the latest code out of SVN if you are experiencing segfaults.  Not just the latest release, but test against the latest code in SVN as well, it could save you a lot of time debugging.

Asterisk 1.6.2.18, 1.6.2.18.1, 1.6.2.18.2 Crash With Microsoft Exchange Unified Messaging

We use Unified Messaging to provide mailboxes to our users in Asterisk along with the added features UM provides over the built in Voicemail app, and we recently upgraded from 1.6.2.11 to 1.6.2.18 and found a new bug.  The bug was introduced in 1.6.2.18, and is fixed in the asterisk 1.6.2 branch in SVN as of 6/29/2011.  The 1.6.2.19-rc1 tag has the fix included as well, so be sure to use that if you are planning to use Exchange Unified Messaging with Asterisk.


Example:

    -- Called 1593@Exchange2010LCYEX2
Segmentation fault (core dumped)

I didn't bother to do much investigation considering the fix is included in 1.6.2.19-rc1.

Wednesday, May 25, 2011

Dynamically Restrict Access to Asterisk SIP 5060 using iptables

We have an asterisk deployment where we have users who work from home so their phones need to be able to connect to asterisk remotely.  In order to limit the number of security threats to our system we lock it down by using the permit and deny settings of SIP Peers to make sure that only those users can get in.

In order to do this for external users we originally allowed every IP to connect, simply relying on using very strong random passwords (40+ character random passwords, unique per extension), and fail2ban to block repeated attempts.  This has been working for us for the last year and a half but I decided to take our security one step further and lock it down to the exact IP of the phone.

We use Aastra 6731i and 6757i devices which have the ability to grab a URL when they boot up, the startup event.  In the aastra.cfg you would have this line:
action uri startup: http://asteriskpbx/aastraphone.php?action=register&ext=$$SIPUSERNAME$$

This tells the phone to grab aastraphone.php at startup.  We use this to keep track of phones, so I decided I would use it to add an addtional layer of IP security to our system.

First, you need to have access to iptables from your web server (or you can pass commands another way, this is a quick and dirty method).

Install & Configure Sudo
apt-get install sudo
add the following lines to /etc/sudoers
#give access to iptables
Cmnd_Alias IPT=/sbin/iptables

#give access to iptables to the account apache is running under, for me www-data
# User privilege specification
www-data ALL=NOPASSWD: IPT

Build aastraphone.php
This will insert an allow rule for the given IP at the top of the input chain.  It will not be removed automatically, so you should probably use some mechanism for going through and cleaning up these entries.  A quick and dirty method would be to put the allow rules in a chain and then flush the chain nightly.  The next time the phone polls the web page it would then be re-authorized for access.  Not a great solution, but for 9-5 shops it would work great at midnight.  A more elegant solution would be to track them in a database and check the database every once in a while for IP's that need to be removed.  


Additionally, the realtime version of this is able to check and see if an IP is supposed to be allowed to connect in from the outside world, this solution does not do that it assumes that if the phone knows how to get to the aastraphone.php file that it is allowed to connect externally.  Because of this it is important to have configured the permit and deny options in sip.conf to prevent peers from being used externally if they shouldn't.

aastraphone.php:
$ext = $_REQUEST['ext'];
if($ext > 0 && is_numeric($ext)){
system("sudo /sbin/iptables -I INPUT 1 -s {$_SERVER['REMOTE_ADDR']} -p udp --dport 5060 -j ACCEPT");
}


Configure IPTables Default Rules
Your system will need to be configured to allow internal hosts to connect, and reject external hosts to connect to your SIP port by default.  Using the following commands should handle this for you.  Using the related/established rule is important so that your communication with your SIP providers stays fully functional.
#by default block all access from the outside work to your asterisk system
iptables -A INPUT -s 0.0.0.0/0.0.0.0 -d 0.0.0.0/0.0.0.0 -m state --state INVALID -j DROP
iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
iptables -I INPUT -p udp --dport 5060 -s 192.168.0.0/16 -j ACCEPT #allow all 192.168.x.x hosts to connect
iptables -I INPUT -p udp --dport 5060 -j DROP #block all others that don't match a rule.  Alternatively you could use the default policy for input drop.
iptables -I INPUT -p tcp --dport 80 -j ACCEPT #allow web traffic for the aastraphone.php file to function


Notes
This solution assumes you leave the web server open to the world, as the phones will need to be able to get to that to gain access to SIP/5060.