Archive for the ‘Engineering’ Category

iphone scribble webapp

Tuesday, July 20th, 2010

As already mentioned through twitter i’m playing around with the iphone and the canvas element to build a scribble webapp running on the device (and android devices as well). It should be possible to save/upload the scribbled image afterwards. Here’s a first code snippet

<!DOCTYPE html>

<html>
  <head>
    <script type="text/javascript" src="http://code.jquery.com/jquery-1.4.2.min.js"></script>
    <script type="text/javascript" src="http://jasonkuhn.net/mobile/jqui/js/jquery.iphoneui.js"></script>

    <meta content="width=device-width; initial-scale=1.0; maximum-scale=1.0; user-scalable=0;" name="viewport" />
    <meta charset="utf-8">
  </head>

  <body style="margin: 0; padding: 0; -webkit-text-size-adjust: none; padding-left: 10px; padding-top: 10px;">
    <button id="save" style="position: absolute; margin-left: 10px; margin-top: 10px;">save</button>

    <script type="text/javascript">
      $(document).ready(
        function() {
          $("body").append("<canvas id='canvas' style='border: 1px solid #000;'></canvas>");

          $("#canvas").attr("width", (window.innerWidth ? window.innerWidth : $(window).width()) - 20);
          $("#canvas").attr("height", (window.innerHeight ? window.innerHeight : $(window).height())- 20);

          $("#canvas").addTouch();

          var ctx = $("#canvas")[0].getContext("2d");

          ctx.lineCap = "round";
          ctx.lineWidth = 15;

          var start_x = null, start_y = null, drawing = false;

          $("#canvas").bind("mousedown",
            function(e) {
              drawing = true;

              start_x = e.pageX - $("#canvas").offset().left;
              start_y = e.pageY - $("#canvas").offset().top;
            }
          );

          $("#canvas").bind("mouseup",
            function(e) {
              drawing = false;
            }
          );

          $("#canvas").bind("mousemove",
            function(e) {
              if(!drawing)
                return;

              var x = e.pageX - $("#canvas").offset().left;
              var y = e.pageY - $("#canvas").offset().top;

              ctx.beginPath();
              ctx.moveTo(start_x, start_y);
              ctx.lineTo(x, y);
              ctx.stroke();

              e.preventDefault();

              start_x = x;
              start_y = y;
            }
          );

          $("#save").click(
            function() {
              var data = $("#canvas")[0].toDataURL("image/png").replace(/^[^,] ,/, "");

              $.ajax({
                 type: "post",
                 url: "/images/upload",
                 data: "image="   encodeURIComponent(data),
                 processData: false
              });
            }
          );
        }
      );
    </script>
  </body>
</html>

Step 1: Drawing

Drawing within the canvas is straight forward. We use mousedown, mouseup and mousemove to recognize the mouse events and draw lines between the coordinates.

Step 2: Upload

Uploading the the scribbled image is straight forward too, thanks canvas.toDataURL. toDataURL encodes the canvas using base64 what allows us to upload the encoded image using ajax or a form.

Of couse we need some server side processing. Using rails this could look like

class ImagesController < ApplicationController
  def upload
    open("#{RAILS_ROOT}/public/images/upload.png", "w") do |stream|
      stream.write decode64(params[:image])
     end 

    render(:update) { |page| page.alert("saved") }
  end
end

Step 3: Iphone

Thanks to this jquery plugin getting this to work on the iphone is as easy as including a javascript file. It translates the iphone’s javascript touch events (touchstart, touchmove, touchend) to mousedown, mouseup, mousemove, … if you addTouch() to the element.

That’s it. Maybe it’s worth to continue working on it and publishing it as a real project, because adding a scribble-webapp (within an iframe maybe?) could be a nice feature for many mobile webapps.

rails plugin testing

Friday, July 16th, 2010

I personally think there is not enough written about rails plugin testing, you have to deal with some problems, though, because you don’t have the rails environment on your side. I want to give 2 tips.

Tip 1:

When you extend ActionController::Base within your plugin, put your extensions into a module within a separate file. Then create another file where you extend ActionController::Base like so

require "my_fancy_controller_extension"

class ActionController::Base
  include MyFancyControllerExtension
end

The first advantage of doing it this way is: you can make your extensions protected

class ActionController::Base
  protected

  include MyFancyControllerExtension
end

and you can test your extensions without dealing with permissions: my_fancy_controller_extension_test.rb

class MyFancyControllerExtensionTest < Test::Unit::TestCase
  class DummyController
    include MyFancyControllerExtension
  end

  def test_whatever
    assert DummyController.new....

    # oh yeah, the fancy extensions are not protected within these tests
  end
end

This leads to

Tip 2:

Don’t try to load the whole rails environment within your plugin tests. Loading the whole environment is a lot of work, dependencies, paths, …. Avoid that, where you can. Instead, create dummy controllers, views, models, … to only build the interface neccessary for testing. Use duck typing! One example:

class TestController
  attr_accessor :request, :session, ... # only what your plugin code needs

  class TestRequest
    attr_accessor :host, ...
  end
end

def MyFancyControllerExtensionTest < Test::Unit::TestCase
  def setup
    @controller = TestController.new
  end

  ...
end

This helps a lot when you don’t know where to start your tests.

mobile-fu rjs

Thursday, July 15th, 2010

hm… hm… hm… hm

I’m a bit unsatisfied with mobile-fu for rails. Sure, it’s great in general, but I want to have different templates for mobile rjs and default rjs and i think it’s a bit clumsy to do it like that:

application.html.erb

def mobile?
  return session[:mobile_view]
end

# distinct between mobile and non-mobile js (mobile-fu)
# only supports :template paramter for mobile-enabled js

def render_mobilized_js(options = nil)
  # if we’re not mobile => render like there is no mobile

  unless mobile?
    return render options if options
    return render
  end

  # render mobilized rjs template

  ops = (options || {}).dup

  ops[:template] ||= “#{controller_name}/#{action_name}”
  ops[:template] += “.mobile_js.rjs”

  return render ops
end

but now I’m able to do this

respond_to do |format|
  format.html
  format.js { render_mobilized_js }
end

But in an ideal world i don’t want to call render at all. I want rails or mobile-fu to do it for me:

respond_to do |format|
  format.html
  format.js
  format.mobile_js
end

Not yet possible - and if it would be possible it would break dependencies. Therefore i keep using my method - unless anyone points me a step towards the elegant solution… anyone?

ruby spreadsheet library

Wednesday, May 5th, 2010

Thumbs up for http://spreadsheet.rubyforge.org/ A ruby library for accessing .xls files. Really comfortable. Just missing a way to access columns by excel-like captions

sheet.row(0)["AA"]

Maybe i just didn’t find it, but nevertheless you can of course extend String, though

class String
  def to_excel_index
    each_char.collect{ |c| ("A".."Z").to_a.index(c) }.
      inject { |sum, n| sum + (sum + 1) * 25 + n + 1 }
  end
end

and use

sheet.row(0)["AA".to_excel_index]

hping2 for the nokia n900

Sunday, January 10th, 2010

I recently played with the “sdk” for my nokia n900. The “sdk” is a cross compilation platform built on scratchbox. The n900 runs maemo, a debian based linux for the arm architecture. I wanted to compile netcat for the phone until i found this, which perfectly runs on the phone. Then i decided to compile hping2 - and you can download my package and install it on your n900. I’ll upload it to the maemo garage, too.

https://garage.maemo.org/projects/hping2/

Webbased Password Managers

Tuesday, September 8th, 2009

In this post I’ll describe problems that arise when you try to develop a webbased password safe.

Imagine an arbitrary company with lots of employees, each using many passwords for many different authentication purposes. Imagine different employees using different operating systems. To avoid them having bad cleartext passwords on their disk, you would like to have a central and universal password manager running on a server keeping the passwords of different users, each having a strong master password to access all his passwords via his browser. You want the password manager to be as secure as possible, beause you have to keep passwords for company related systems and you want it to be as secure as any existing client-wise password manager, of course.

A naive approach, at first. Any attempt to access passwords has to be encrypted, of course, especially when we send passwords over an (insecure) network. Therefore we have to use SSL and the password manager has to enforce HTTPS. If we are trusting the server (that means: we have to ensure that the server won’t get compromised), we won’t have to encrypt the passwords on the server and we can store them in simple text files. But if the server ever gets compromised, all passwords are lost. To avoid cleartext passwords saved permanently on disk we have to encrypt them like every password safe does. We decrypt them when a user is authorized and wants us to and we store them within the server’s memory, but if someone can access the RAM the passwords are lost, too.

A password safe typically only stores passwords of a single user. In contrast, our webbased password safe stores passwords for the whole enterprise. Therefore, a server-compromise is more critical and imagine employees interested into reading other employee’s private mails, social network accounts and so on (aka insider attacks). We can solve this problem by never keeping a password in cleartext on the server, neither RAM, nor HDD. The encryption has to happen on the client. Therefore, we have to encrypt them on the client (within a browser). The guy compromising the server will get the encrypted files, but he won’t get the clear text passwords easily. Of course, he can bruteforce the master password, use cryptanalytical methods or just stay behind another employee’s neck while he is typing the master password, but every password manager has to deal with that possibility (but we have a central login now) and we can enforce strong master passwords and encryption centerally. This paradigm is related to Host-Proof-Hosting (”Host sensitive data in encrypted form, so that clients can only access and manipulate it by providing a pass-phrase which is never transmitted to the server“).

The encryption and decryption on the client could be done with javascript (ecma-262 and clipperz), but how secure could, for example, an AES javascript-implementation be (not from a cryptanalytical point)? Is it guaranteed that passwords won’t be stored for long time within the client’s RAM, because we have to wait for javascript’s garbage collector? Usual password safes are written in C and they can manipulate memory directly. A javascript implementation is not able to do that. To show that, lets take a look into our memory while executing this with firefox 3.0.6 in a virtual machine running Debian Lenny and using the KVM - virtual machine monitor:

var key = "";

for(var i = 0; i < 3; i++) key += "M";
for(var i = 0; i < 3; i++) key += "1";
for(var i = 0; i < 3; i++) key += "K";
for(var i = 0; i < 3; i++) key += "Y";
for(var i = 0; i < 3; i++) key += "9";

key = "";

Suppose, ‘key’ is a cryptographic key. We concat the key to be sure that we don’t have it as a complete string before we’re using it within the javascript code. We execute it and dump the memory using the kvm monitor mode:

pmemsave 0 134217728 memory.dmp

If we search for the key MMM111KKKYYY999 within memory.dmp we’ll find it. No surprise, javascript uses reference semantics, but the garbage collector doesn’t free the (now) unreferenced string. There is no way we can overwrite the portion of memory ‘key’ was using. There are good reasons to let us not do that, because direct memory manipulation with javascript would be a very bad idea.

After we’ve left the website we dump memory again and this time we won’t find the key. Firefox 3.0.6, Chrome 2.0.172.43, Internet Explorer 6 and Opera 10 all show this behaviour. Therefore, a webbased password manager should force users to leave the page after a certain amount of time and - maybe - the password manager should only work with approved browser versions (versions that show this behaviour), because it is possible other browser (versions) store it even longer. But that will result in less flexibility.

Some huge problems remain, though. The largest: injecting malicious javascript code into the client. The javascript code is responsible for encryption and decryption on the client, but the code is loaded from the server dynamically. A server compromise is therefore still the biggest issue, because an attacker could inject malicious code into all clients and steal all passwords. Therefore, the code itself has to approved in some way. Clipperz, for example, is of course aware of this problem and agrees: “there are no perfect solutions to avoid this problem“.

In a nutshell, a webbased password manager could have different levels of security.

  1. Security only lies within secure transportation (HTTPS) of passwords to the client to avoid sniffing passwords. Cleartext passwords exist on clients and on the server hosting the passwords, both for an (nearly) arbitrary amount of time.
  2. Cleartext passwords only exist on clients, but for an (nearly) arbitrarty amount of time.
  3. Cleartext passwords only exist on clients for a predefined period of time.

Option 3 is the most inflexilible one, because we have to use approved components only (Browser, Javascript implementation, Operating System’s clipboard implementation, Javascript-Code and so on) and whether we decrypt passwords only on the client or not, we have to trust into the server, because we have to trust into the application and if the server is compromised, an attacker could inject malicious code.