Utvecklingen går framåt!

För 10 år sen kunde man inte få precision med civila GPS mottagare. President Clinton slog av störsignalen Selected Availablity och vips började vi få bra mottagning. Kort därefter kom man på geocaching, och med tiden fler location based games.

Geocaching.com hade pocket queries, nerladdning av många koordinater i en GPX fil länge. Av historiska skäl gick de via mail (så…. Nittiotal). Jag noterade för länge sen att de även fanns online (för iPhone kommer åt dem online). Idag kom två viktiga förbättringar: man kommer åt pq’s online med webbsidan, och man kan få hem 1000 geocacher (istället för 500) per pq.

Nice!

Geotagging med kamera och GPS, Del 2

Så! Nu har du läst mina tidigare inlägg om Geotagging och varit ute och fotat en massa under tiden som din GPS har varit igång. Vad är nästa steg?

Jo, nu skall vi slå ihop två datakällor:

  • Fotorna som vet när dom togs (metadata innehåller tidpunkt)
  • GPS Tracklog som vet var när du var var.

Bilden nedan visar foto-metadata till vänster och tracklog till höger;

Som synes innehåller bilden en massa saker, inklusive tidpunkten fotot togs (i den tidzon jag hade ställt in på kameran). Tracklogen verkar ha en upplösning på ungefär en minut mellan punkterna, vilket är mer än tillräckligt bra (standardinställningar för tracklog brukar räcka fint till geotagging, du behöver inte krångla till det).

Så, först ut är att få över trackloggen till datorn. Med Garmin Colorado, Oregon och Dakota är det bara att kopiera över filen current.gpx till datorn. Med många andra GPS;er behöver man lite specialprogram så som t.ex. Garmin MapSource eller EasyGPS för att få över data från GPS:en. Laddar du in filen med MapSource är det värt att tänka på att Garmins egna filformat kanske inte stöds av så många verktyg, så välj standardfilformatet GPX när du sparar tracklog till fil.

Sen så skall vi slå ihop GPX-filen med bilderna. Här finns en bunt program att välja bland:

  • C O P I K S – PhotoMapper. Snabbt och smidigt, få funktioner.
  • GPicSync. Många funktioner, kan göra mycket mer än bara lägga till koordinat till bilden. Tyvärr assegt (eftersom det startar om exiftool gång på gång, vilket innebär att Perl startas om varje gång.)
  • Garmin Basecamp som en del geocachare, joggare m.m. redan använder (tipstack till Olssonivalda).

Och tusen andra program. Vi utgår ifrån Copiks PhotoMapper eftersom det är snabbt och enkelt.

Så, vad gör man då?

  • Ange kamerans tidzon (längst ner till vänster). Sommartid har CEST +2, vintertid CET +1. Om osäker, kamerans inställningar. Du kan ju alltid testa att tagga, och sen göra om med andra inställningar. (Är du riiiktigt rädd kan du göra en backup först, men ärligt talat behöver du inte vara rädd.)
  • Kontrollera, kom du verkligen ihåg att ställa kamerans klocka? Går den tio minuter fel, så kan du experimentera med Time correction för att kompensera, smart va?!
  • Gå till File menyn högst upp till vänster och välj Import GPS Data. Välj din tracklog fil (current.gpx el.dyl)
  • Gå till File menyn högst upp till vänster och välj Import Images. Välj bilderna du tagit.
  • Kontrollera att du tycker bilderna verkar ha taggats på rätt plats (annars, kolla igenom Camera timezone och Time correction)
  • Markera bilderna (markera en av dem och tryck Ctrl-A är snabbaste sättet att markera alla) och tryck på knappen  Tag selected images.

Nu är bilderna geotaggade! 🙂

Kanske skriver nått om att titta på Geotaggade bilder i Picasa, Flickr osv senare. Om inte annat kan du ju leka med den lilla knappen Export to Google Earth om du Google Earth installerat;

A failure of Imagination: JavaCard 3.0 XSS + XSRF

Curiously Java Cards have been transformed into webservers which you are supposed to browse to, deployed on 127.0.0.1. The example app implements the two most common web vulnerabilities, XSS Cross Site Scripting (Persisted, the most severe variant) and XSRF/CSRF Cross Site Request Forgery. Or to rephrase it, developers have no control over what happens in the application.

It is a failure of imagination, that a standard and supporting programming guidelines in january 2010 standard ignores over a decade of learning Web security.  And is the failure acceptable, given that we allready have been proven over and over again by GNUCITIZEN and others that embedded web servers are targets of web attacks?

List of code vulnerabiltities:

  • Servlet does not validate data in doGet().
  • Servlet does not encode output in doGet().
  • Servlet performs write upon GET, HTTP guidenace violation.
  • Servlet does not implement anti-XSRF tokens.
  • Database layer does not validate data.
  • No user authentication/authorization/session model.

Why is it that new technologies always excuse forgetting old teachings?

Maybe there is one explaination: embedded developers are not used to writing web applications. Therefor they are unprepared for the new challenges Java Card 3.0 Connected Edition faces them. And maybe they don’t even know it.

PersistenceServlet.java

package com.sun.jchowto.persistence;

import java.io.IOException;
import java.io.PrintWriter;

import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * A Simple Persistence Servlet.
 */
public class PresistanceServlet extends HttpServlet {    /* (non-Javadoc)
     * @see javax.servlet.http.HttpServlet#doPost(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse)
     */

    @Override
    public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {

        String op = request.getParameter("op");
        String item = request.getParameter("item");

        if (op != null) {
            if (op.equals("Add")) {
                if (item != null) {
                    Database.addItem(item);
                }
            } else if (op.equals("Delete")) {
                if (item != null) {
                    Database.delete(item);
                }
            }
        }

        response.setContentType("text/html");
        PrintWriter out = response.getWriter();
        RequestDispatcher dispatcher = null;

        dispatcher = request.getRequestDispatcher("/WEB-INF/header.i");
        dispatcher.include(request, response);

        out.println("        <tr>");
        out.println("            <td bgcolor=\"#FFFFFF\" align=\"center\" valign=\"middle\">");
        out.println("                <table bgcolor=\"#000000\" border=\"0\" width=\"100%\" cellspacing=\"1\" cellpadding=\"15\">");
        out.println("                    <tr>");
        out.println("                        <td align=\"center\" bgcolor=\"#FFFFFF\">");

        out.println("</b><big><big>Simple Database</big></big></b>");
        out.println("<form method=\"get\" action=\"database\">");
        out.println("   <table border = 0>");
        out.println("       <tr>");
        out.println("           <td>Item : </td><td colspan=2><input type=\"text\" name=\"item\"></input></td>");
        out.println("       </tr>");
        out.println("       <tr>");
        out.println("           <td> </td>");
        out.println("           <td><input type=\"submit\" name=\"op\" value=\"Add\"></td>");
        out.println("           <td><input type=\"submit\" name=\"op\" value=\"Delete\"></td>");
        out.println("       </tr>");
        out.println("       <tr>");
        out.println("           <td colspan=3><hr></td>");
        out.println("       </tr>");
        out.println("       <tr>");
        out.println("           <td colspan=3><b>Items in Database</b></td>");
        out.println("       </tr>");
        out.println("<tr>");
        out.println("   <td colspan=3><textarea readonly rows=\"5\" cols=\"20\">");
        if(Database.getItems().size() <= 0) {
            out.print(" \n \nDatabase is Empty;\n \n ");
        } else {
        for (String str : Database.getItems()) {
            out.println(str);
        }
        }
        out.println("</textarea></td>");
        out.println("</tr>");
        out.println("   </table>");
        out.println("</form>");

        out.println("                        </td>");
        out.println("                    </tr>");
        out.println("                </table>");
        out.println("            </td>");
        out.println("        </tr>");

        dispatcher = request.getRequestDispatcher("/WEB-INF/footer.i");
        dispatcher.include(request, response);

    }
}

.

Database.java

package com.sun.jchowto.persistence;

import java.util.Vector;

/**
 *
 */
public class Database {
    private static Vector<String> items = new Vector<String>();

    /**
     * @param item
     */
    public static void addItem(String item) {
        if (!items.contains(item)) {
            items.addElement(item);
        }
    }

    /**
     * @return
     */
    public static Vector<String> getItems() {
        return items;
    }

    /**
     * @param item
     * @return
     */
    public static boolean delete(String item) {
        return items.removeElement(item);
    }
}