Tuesday 20 August 2013

Basic Security - Part 2 - Basic Auth for your Servlet

In our previous article we went over how to implement SSL certifications to our Tomcat7 server using a combination of an unsigned SSL certification, a keystore and enabling a secure port and protocol to be used for HTTPS requests.

The next step is to provide basic authentication for your servlets running on the Tomcat instance. After validating that the server the client is connecting to is the one they actually meant to connect to, we should require them to login before sending encrypted sensitive material to them.

Open up your tomcat-users.xml file and make sure you have a unique login and password created referencing a unique role. (which we did initially in step 1)

<tomcat-users>
   <role rolename="security_role_101"/>
   <role rolename="security_role_something" />
   <user username="UniqueUsernameForSomething"
      password="SuperLongPassword6666"
      roles="valid_mobile_user"/>
   <user username="super_admin_login"
      password="superComplicatedPass6"
      roles="security_role_101"/>
</tomcat-users>

Once a user-connects we are going to make the servlet challenge for username UniqueUsernameForSomething.

To do this, open your project and go to the web.xml file. Generally this is found under the folder WebContent/WEB-INF/

Add the following between the fields.

<security-constraint>
   <web-resource-collection>
      <web-resource-name>App-Name</web-resource-name>
      <url-pattern>/*</url-pattern>
   </web-resource-collection>
   <auth-constraint>
      <role-name>security_role_101</role-name>
   </auth-constraint>
   <user-data-constraint>
      <transport-guarantee>CONFIDENTIAL</transport-guarantee>
   </user-data-constraint>
</security-constraint>

<login-config>
   <auth-method>BASIC</auth-method>

</login-config>

This forces basic auth on any URL route for www.servername.com/* and checks that the passed in username and password is in the role "security_role_101". The transport guarantee of CONFIDENTIAL tells the app to only send the data in a way which ensures the information cannot be changed or observed during transmission.

Compile your war and redeploy. Browse to your test URL of www.servername.com:secureport/mypage and it should now prompt you for your login details.

Enjoy.

Friday 16 August 2013

Basic Security - Part 1 - Secure your Server

Often in the mad dash to get a feature out or even the coveted MVP for your new startup the first thing that gets left behind is security.

In this tutorial I'm going to give you the bare-bones required to secure a Tomcat7 server (on a UNIX system) to try and reduce your risk. It's by no means an in-depth look at security but this article and the next few I'll write will let you have some measure of surety that any Tom, Dick and Harry are not listening to your every message over the internet.

First we are going to look into our Tomcat users file and ensure there are no default usernames/passwords being used. Early in development while you are still chopping and changing code and technology we lock in these basic authentication mechanisms with dummy or simple data so we can get on with what we need to do. Then of course, forget to go back and strengthen the security.

Open you Tomcat Users configuration file and make sure your passwords are atleast 10 characters long and your usernames are unique. Don't use admin, don't use default, make it unique please.

$ sudo vi /etc/tomcat7/tomcat-users.xml

You can also strip roles from users unless they are required. You don't need every user to have roles manager and manager-gui. These for example should either be unused or with a master-admin user-account.

<tomcat-users>
   <role rolename="security_role_101"/>
   <role rolename="security_role_something" />
   <user username="UniqueUsernameForSomething"
      password="SuperLongPassword6666"
      roles="valid_mobile_user"/>
   <user username="super_admin_login"
      password="superComplicatedPass6"
      roles="manager,manager-gui"/>
</tomcat-users>

I also secure how a user connects to our server based upon how they are connecting. For example, someone trying to access www.servername.com/admin/* will be going through a different security mechanism using a completely unique username and password than say an encrypted message being sent from a users device to www.servername.com:secureport/rest/*.

Next step is to provided some surety to users connecting that this server is the correct server they were wanting to connect to. Below we are going to update our Tomcat instance to use an unsigned SSL certificated. In production you would replace your unsigned SSL certificate for a signed certificate.

To generate your own unsigned certificate type in the following:

$ /usr/bin/keytool -genkey -alias tomcat -keyalg RSA

What's this doing? keytool is a certificate utility that is generating you a RSA certificate known as 'tomcat'. It places this in your home-directory (unless otherwise specified) in the .keystore file. Make sure set and don't forget the keystore password you'll be prompted to enter.

Next we need to update our Tomcat server configuration to use this keystore.

$ sudo vi /etc/tomcat7/server.xml

Then put in the following, be sure to remove any other defaults like a connector for port 8080.

<!-- Our original open, insecure port for development
<Connector executor="tomcatThreadPool"
   port="8080" protocol="HTTP/1.1"
   connectionTimeout="20000"
   redirectPort="8443" />
-->

<Connector port="8443" SSLEnabled="true"
   maxThreads="150" scheme="https" secure="true"
   protocol="org.apache.coyote.http11.Http11NioProtocol"
   keystoreFile="/path/to/.keystore" keystorePass="password"
   clientAuth="false" sslProtocol="TLS" />

Save the settings and reload your Tomcat7 service.

$ sudo service tomcat7 restart

You can test if this works by by going to:

https://www.servername.com:secureport/

Browsers like Chrome will check with you before proceeding to the site because it has an unsigned SSL certificate.

Next article will be adding basic auth to your servlet running on Tomcat and then getting an iPhone device to authenticate properly before sending data.



Tuesday 25 June 2013

Using PHP to send emails on a Ubuntu Server

This is a rather basic way of quickly getting PHP to send an email when running on a Ubuntu server. A couple of prerequisites must be fulfilled first.

For this example we are going to use sendmail with added libraries for SMTP over TLS. (a requirement for using Google Mail) To ensure we have the packages we need to run the following:

 $ sudo apt-get install sendmail  
 $ sudo apt-get install libio-socket-ssl-perl libnet-ssleay-perl  

To test that this is working, use an existing Gmail account that you have access to and type the following in:
 sendemail -f from@email.com -t to@email.com -u Testing -m "This is a test"-s smtp.gmail.com:587 -o tls=yes -xu from@email.com -xp  

Put in the email you are sending from after -f, who you are sending to after -t and provide your gmail username after -xu. After you hit enter it will ask you for the password, this is better than having your password in-line for that command as it will then be on your command-line history.

If all goes well you will get:
 Jun 25 14:35:37 server-name sendemail[10667]: Email was sent successfully!  

Next we are going to take advantage of the PEAR framework to get the Mail module for our PHP code. Check that you have PEAR by:
 $ pear version
PEAR Version: 1.9.4
PHP Version: 5.3.10-1ubuntu3.6

If not installed you can quickly do this by running:
 $ sudo apt-get install php-pear  

We need the module Mail.php for this example, using the PEAR framework to get this is as simple as running:
 $ sudo pear install Mail  

Now we can setup our page and PHP code. This will be a basic HTML form that attempts to send an email when the submit button is pressed.

The PHP code:
 <?php  
     require_once 'Mail.php';  
     $recipients = "to@email.com";  
     $headers["From"] = "from@email.com";  
     $headers["To"] = "to@email.com";  
     $headers["Subject"] = "Expression of Interest";  
     $msg = "Hi, ".$_POST['email']." is interested in our product!";  
     $smtpinfo["host"] = "smtp.gmail.com";  
     $smtpinfo["port"] = "587";  
     $smtpinfo["auth"] = true;  
     $smtpinfo["username"] = "from@email.com";  
     $smtpinfo["password"] = "password";  
     if($_POST['send_email']) {  
         $mail_object =& Mail::factory("smtp", $smtpinfo);  
         $mail_object->send($recipients, $headers, $msg);  
     }  
 ?>  


The HTML code:
 <form action="" method="POST" id="contactFormHeader">  
    <input type="hidden" name="send_email" id="send_email">  
    <label for="name">Name</label>  
    <input type="text" name="name" id="name" class="required" />  
    <label for="email">E-mail</label>  
    <input type="text" name="email" id="email" class="required email" />  
    <button type="submit" name="submit" id="submit">Submit</button>  
 </form>  

There you go, a basic PHP driven HTML contact form that sends an email via SMTP over TLS by way of your Gmail account.


Tuesday 18 June 2013

Dynamic Divs via JQuery

In a secure session for our customers with XXX company, we wanted to give them a simplistic wizard to modify as much data as possible in a consistent and context relevant way. This wizard took a gigantic form built and parsed by PHP and added some dynamic content and validation to it via JQuery.

i.e.
<form>  
   <div>  
   //heaps of content  
      <table>  
      //heaps of content  
      </table>  
   </div>
   <div>
   //more something
   </div>  
</form>  

My first step was adding in id's for every div, every table, everything. You can never have enough items in your code identified.

<div id="this_is_a_div">  

Then I broke each section of the form into div's that are contextually related and had them not displayed by default. (a common class would be preferable to manually styling each div)

<div id="address_container" style="display:none;">  
   <div id="street_container" class="pre_defined_css">  
      <small class="input_info">Some random tool tip</small>
      <label for="street" class="label">Street</label>
      <input type="street" name="street" id="street" value="" class="input"class="label" /<
   </div>
</div>

This allows you to insert fancy Javascript. I personally like JQuery, a Javascript library which features a simple and powerful API to manipulate HTML. (works well with PHP too)

Assuming we have a button that activates a JS function like so:

<button type="button" id="reveal" class="button special-css" onClick="return reveal('address_container')">Reveal Button!</button>

We can build our function reveal. I'll show standard Javascript first then JQuery.

 function reveal(option) {  
   if(option == "a_div") {  
    document.getElementById("address_container").style.display = "block";  
    document.getElementById("another_div").style.display = "none";  
   }  
 }  

Or you can do it via JQuery
Edit: Don't forget to import JQuery first!!

 <script src="js/libs/jquery-1.8.2.min.js"></script>  

 function reveal(option) {  
   if(option == "a_div") {  
    $('#address_container').show();  
    $('#another_div').hide();  
   }  
 }  

Additionally, you can use the method toggle to contextual swap between show and hide calls depending on element state.

This allows you to build a 'wizard' or more simplistic form where each div is rendered by using 'next' buttons instead of showing all field and forms at once to the end-user.


Monday 10 June 2013

Implementing Maven into an existing project

My current project requires using Apache Ant to build our Java applications into WAR (Web Application Archives) files for Tomcat which in turn we use to run our service on a virtual machine. I've had a number of problems with this as we have two developers, one (me) primarily developing on Windows 8 the other on iOS.

Our Tomcat service runs on the same Linux server (Ubuntu Precise) however as we commit back and forth via GitHub we are overriding each others environmental variables (despite trying to get the other developer to use .gitignore more). To restore some sense of consistency and not to have to constantly worry about different environments I've decided to try out Maven.

Maven is a project management and comprehension tool (Maven) and by structuring our project files and libraries I hope it helps fix a lot of our dependency and co-development problems as we continue to add developers to our software project.

I'm using Eclipse with the Android Development Kit plugin (https://developer.android.com/sdk/index.html). You can install new software to Eclipse by going to the top menu, clicking Help then Install New Software.


From there you can select "All Available Sites" to "Work With" and search for maven. Install the Maven plugins and restart Eclipse when asked to.


Because I want to import an existing project into the Maven format, I'm going to go ahead and create a new Maven Project via New -> Other -> Maven -> Maven Project

Using the default Workspace location and a simple project. (FYI there is a Tomcat archetype, but I found it unwieldy to use as a beginner to Maven). My GroupId is the namespace we are using for all our packages previously (com.businessname), the ArtifactId is the Project name and change the Packaging to 'war' and fill in the other fields as you see fit.

I placed my previous projects code under src/main/java/com/businessname/subfolders. Change this as you need to, I wanted to keep my previous package namespacing "com.businessname.*" intact. There will usually now be a hundred or so errors where dependencies are now failing.

Right click in the Package Explorer to reveal the Maven contextual menu and go to Maven -> Add Dependencies. It gives you the ability to search for your missing dependency, I find it easy to copy in the import missing.library.name.* and search for that directly, adding only what I really need.

You can see the dependencies being updated in pom.xml in the projects root directory. The POM file is a Project Object Model written using XML. It contains the brains of the projects paths and dependencies. It allows you to set rules based on your resources so only specific revisions are included or excluded.

Example: Snippet of a pom.xml requiring Tomcat7







In some cases there are no Maven supplied dependencies for Java libraries you need. You can still manually place them into the pom.xml so they are treated as a core-dependency of your code.

Example: Adding in net.sf.json.lib dependency to Maven







Update: Thanks to Petar Tehchiev for his answer to this dependency problem, you need to also include the classifier tag to specify which JDK to use. [stackoverflow]

When we are ready to build this war file, we need to ensure that our web.xml from our previous Ant-based project has been brought across and added into our pom.xml.

The easiest way to add the requirement into your section of your pom.xml file.
Ensure that you have copied your WebContents folder (or equvilent) to the path specified in the below tags PATH.
Example: Adding in the web.xml file to our list of Maven plugins








Run-As and make a new Maven Build configuration. Goals should be war:war and with that you can Run and build your WAR file. If it goes well you will get a lot of output including:

[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------

I deployed to my Tomcat service only to have a few errors popup. Not all dependencies are immediately obvious, especially when you inherit random projects like I frequently do. The error in my /var/log/tomcat7/servername.date.log was:

java.lang.ClassNotFoundException: com.sun.jersey.spi.container.servlet.ServletContainer

Which isn't a completely new problem if you spend a second googling it. Mkyong.com shows how to resolve this quickly and also reveals how powerful Maven is at it's core. By adding a new dependency (this time groupid: com.sun.jersey and artifactid: jersey-server) and building the WAR again we have fixed this dependency issue and can continue to do so.

More to come on Maven in later articles.


Sunday 9 June 2013

Development Environment Setup Part 2 - Vagrant

Continuing on from Part 1 we now have our base requirements for setting up a new development environment. Using Git Shell/CMD on Windows (or terminal on Mac) create a new folder my_vagrant_folder where we will store the configuration for our soon-to-be-created virtual machine.

Go into that directory and an initialise the vagrant configuration file using the following commands.


 $ cd my_vagrant_folder  
 $ vagrant init precise32 http://files.vagrantup.com/precise32.box  

Vagrant will output some information telling you that it has created a Vagrantfile within that directory. A Vagrantfile contains setup information for a virtual machines provisioning and configuration. It's Ruby based but contains simple enough line by line configuration variables that you can easily modify it without having a background in Ruby.


The above vagrant init command defines a base-configuration precise32 using the box package found in that URL. It's a default Ubuntu Precise virtual machine provided by Vagrant. You can also '$ vagrant init' without  the specific commands to see the default values that go into a Vagrantfile when it's not provided configuration options. You won't be able to proceed further until you fill that information in.


Once you are happy with the Vagrantfile, or using the precise32 one provided above, it's time to get Vagrant to tell VirtualBox to import that Ubuntu box and set it up locally.


 $ vagrant up  

This is also the command you will use when in this folder from now on to turn your virtual machine on via vagrant. It sets up port 2222 by default so you can SSH into the machine to manage it. Other useful commands are '$ vagrant suspend' and '$ vagrant reload' when you want to turn off the VM and completely reload it (for example, if you have changed your Vagrantfile configuration to include new port-forwarding options)


I usually like having port 80 (HTTP) and 8080 for tomcat redirected for web-development. For consistency sake I make port 80 redirect to 1987 or something similar because of Unix-systems locking out redirects on registered ports below 1024 for applications not run as root (virtualbox manual).  This can be done in the Vagrantfile like so:


 config.vm.network :forwarded_port, guest: 8080, host: 8080  
 config.vm.network :forwarded_port, guest: 1987, host: 80  

Run the following to reload the VM if it is currently running so the changes take effect.

 $ vagrant reload 

The Vagrant Documentation includes a lot of good information about this, setting up private networks and creating synchronised folders for easy sharing between the VM and your host system. Although I tend to utilise SCP over this. (SCP is a tool for securely coping files between devices via SSH, remember for your VM you will use port 2222 not 22 for SSH)

Synchronised folders might be helpful if you prefer not to use SCP and/or more comfortable using FTP/SFTP to copy resources across. Depending on your VM setup (it's NAT by default) you will run into one hassle after another port-forwarding the correct ports to establish a FTP handshake then working out which upper-range port it decides to use for the data transfer. (A bridged network helps)


Once your virtual machine is running we can move onto setting up GitHub.


Saturday 8 June 2013

Development Environment Setup Part 1 - Requirements

One of the first things I do when beginning a new project is prepare my development environment. I do this because there are a number of problems that tend to creep up on every project that can be headed off early by tackling this first. The big issues are environment availability, consistency, and the ability to recover from disasters. Availability is merely access to the system and the resources required to program. This is your operating system, virtual machine, your code repository and libraries required to run and test your application.

Not only do you need your libraries available, they have to be the correct ones for your programming project. It doesn't help if you have begun coding using new features of Oracle Java 7 and you have Sun Java 6 running every other machine. Consistency is hugely important as you begin to add more human resources to a project and begin to work in separate branches. It can lead to a lot of pain when you need to merge to master or begin testing across different platforms.

Finally you need to consider disaster recovery. What do you do when your hard-drive fails, the OS is unresponsive, your code goes missing or anything that renders your primary development environment unavailable? Good disaster recovery doesn't require a huge amount of thought given how ubiquitous the internet and cloud-based technologies are these days.

The base components of any of my new environment builds is a cocktail of Vagrant, VirtualBox and GitHub. All free to use and readily available online. Oracle's VirtualBox is our virtualisation product which Vagrant will use to build new virtual machines based off a simple configuration Vagrantfile we create. GitHub will be our repository of choice to safely backup and store our code as we delve into a new software project.

Note: The free version of GitHub has your code publicly available. A paid-subscription is required to have private repositories.

What we are going to have at the end here:
  • Easy to configure and reproduce Ubuntu virtual machine
  • Using Vagrant for the virtual machine initial setup and configuration
  • VirtualBox which'll handle the virtualisation
  • GitHub for our easy to use and access online repository for our code

First step, download all there and install in this order.
[Windows and Mac]
Download and Install GitHub
Download and Install VirtualBox
Download and Install (the latest) Vagrant

Once we have all these we'll get into the basic configuration.