30 mai 2012

Secure cookies

import hmac

# hashing with HMAC
CHEIE = "secret"

def hash_str_hmac (s):
    return hmac.new(CHEIE, s).hexdigest()

def make_secure_val(s):
    return "%s|%s" % (s, hash_str_hmac(s))

def check_secure_val(h):
    val = h.split('|')[0]
    if h == make_secure_val(val):
        return val

Mecanism:
* vrem sa setam un cookie de tipul: camp=valoare
Daca setam cookie-ul in acest format, el va fi usor de modificat din browser-ul clientului.
Altfel, putem sa ii atasam un hash, noua valoare devenind: valoare|hash(valoare)
* ca algoritm de hashing, putem folosi md5 sau chiar mai sigur, hmac - acesta implica si contributia unei chei secrete cunoscute doar de noi ("secret")
* noul cookie este transmis serverului, exemplu de format:  user_id=3|890b62425d300574b7bcdf60a5bc6059
3 este valoarea care ne intereseaza, pe cand sirul ce ii urmeaza este criptarea cu cheia secreta CHEIE a numarului 3. ~ make_secure_val()
* pe server, din cookie este extrasa valoarea 3, si hash-ul lui 3 este comparat cu hash-ul primit in cookie. Daca valorile nu coincid, valoarea extrasa este considerata invalida. ~ check_secure_val()

In acest fel, serverul este sigur ca cookie-urile nu au fost modificate fortat de client.

* Setare cookie (in webapp2):
self.response.headers.add_header('Set-Cookie', 'user_id=%s' % mycookie + ';Path=/')
* Stergere cookie - cookie-ul nu se chiar sterge, ci valoarea campului respectiv devine vida
self.response.headers.add_header('Set-Cookie', 'user_id=; Path=/')
" Path=/ " este optionala, dar este important ca de fiecare data cand se doreste suprascrierea, cookie-ul sa fie referit de pe aceeasi cale (path). Nu pot exista 2 cookies care sa contina informatii despre acelasi camp ("user_id"), decat daca sunt salvate in locatii/cai diferite.

11 mai 2012

Scoli de vara 2012

1) Scoala de vara IP Workshop
Durata: 2 saptamani, 30 iulie-12 august 2012
Locatie: Calimanesti, jud. Valcea
Cursuri disponibile:
  • Administrarea sistemului Linux
  • Dezvoltarea aplicațiilor de rețea
  • Grafică pe calculator
  • Introducere Android
  • Programare iOS
  • Programare pentru Blackberry Playbook
  • Programare Python
Cost: studenti - 650 RON (600 inainte de 1 iunie) & profesori 400 RON (350 inainte de 1 iunie). Costul include cazarea, 3 mese pe zi, materialele pentru curs si excursiile
Contact: http://calimanesti.ipworkshop.ro/2012/?page_id=27
Mai multe detalii: e-mail la alex@ipworkshop.ro, informatii despre editia de anul trecut


2) Scoala de vara de programare functionala
Durata: 5 zile, 18-22 iunie
Locatie: UPB, Bucuresti
Curs: programare in Scheme, Haskell, Erlang , paradigme de programare
Cost: -
Contact, detalii: pe situl lor


3) Scoala de vara NCIT
Durata: 3 saptamani, 4 iunie-22 iunie
Locatie: UPB, Bucuresti
Curs: stagii in domeniul HPC (simulari in seismologie, meteorologie, dinamica moleculara, astrofizica, procesare de imagini satelitare)
Cost: -
Inscriere si detalii: Stagii pe bune


4) Open source summer school

Durata: 3 saptamani, 4 iunie-22 iunie
Locatie: UPB, Bucuresti
Curs: managementul proiectelor software open source, sisteme pt controlul versiunii, Python, interfete grafice, POO, design patterns, testare unitara, dezvoltare Android.
Cost: -
Inscriere si detalii: open-source.cs.pub.ro

Google Application Engine si GQL

Google Application Engine este o platforma pentru deployment-ul unor aplicatii web scrise in mai multe limbaje de programare (gen JSP, Python, Ruby). Este usor de instalat, de rulat, e gratuit in limita a 1GB de date, ofera acces la un Datastore, iar pentru Python ofera un framework numit webapp care usureaza construirea aplicatiilor. (descrierea nu se opreste aici)

GQL - este un limbaj asemanator SQL folosit in GAE care insa suporta un singur tip de query : "select [parametri]" - acesta returneaza o liste de obiecte de tipul tabelului considerat. GQL nu este o baza de date relationala, adica nu suporta JOIN-uri, interogarea a mai mult de un tabel/query, iar in campul where din select se poate pune o singura coloana (din motive de rapiditate). In schimb, coloanele nu sunt fixate: pot exista oricate si chiar pot fi schimbate de-a lungul programului.

De exemplu: pentru definirea unui tabel in Datastore mai intai se construieste o clasa al carei nume va fi numele tabelului, cu variabile reprezentand campurile acestuia si tipurile lor.
from google.appengine.ext import db
class User (db.Model):
    username = db.StringProperty (required = True)
    password = db.StringProperty (required = True)
    email = db.StringProperty (required = False)
Crearea clasei User este echivalenta cu crearea tabelului in baza de date (acest lucru este specificat de db.Model care reprezinta clasa mostenita).
Oriunde in program, se poate crea acum un obiect de tip User pe care sa il inseram in baza de date:
u = User(username = "boom", password = "ble", email = "bee@gmail.com")
u.put()
Tabelul User, la fel ca orice tabel din GQL, contine un camp suplimentar numit id ca o cheie primara, generat automat. Daca vrem sa aflam id-ul inregistrarii ce tocmai am inserat-o, se foloseste:
id = u.key().id()
Consultarea tabelului User se poate realiza foarte simplu:
entries=db.GqlQuery("select * from User")
for entry in entries:
    self.response.out.write(entry.username + " " + entry.email)
"entries" furnizat este o lista de obiecte de tip User, si campurile fiecarui User se acceseaza cu "."
Pentru stergerea unei inregistrari se poate folosi:
db.delete(entry)
, unde entry este un element din entries (lista returnata de select).