Software per gestire una flash policy in C
Usare i socket in flash è stato per molto tempo fin troppo facile, quasi intuitivo e questa condizione ha fornito ai soliti malintenzionati la possibilità di creare molti problemi (per esempio caricamento di informazioni senza che il navigatore se ne accorgesse e “rubandole” da altri siti, oppure effettuare connessioni inopportune e di massa verso server legittimi). Per evitare questo dalla versione 9.0.124.0 (e successive quindi anche la 10.x attualmente in uso) per poter effettuare connessione remote è indispensabile che il server a cui si desidera collegarsi fornisca una “flashpolicy”, ovvero un file XML dove sono contenute informazioni relativamente a quali server si possono collegare e con quale frequenza/condizioni a quello dove la policy è servita.
Ad ogni tentativo di accesso remoto il “flash player” effettua una richiesta al server di destinazione usando prima di tutto la porta TCP 843 e poi un eventuale altra porta specificata da chi ha creato l’applicativo in flash. In caso nessuna flashpolicy venga trovata allora la connessione non è consentita, in caso contrario il file XML viene analizzato e l’accesso è effettuato solo se esplicitamente consentito. Il file XML ha un formato molto simile a questo :
<?xml version="1.0"?> <!DOCTYPE cross-domain-policy SYSTEM "/xml/dtds/cross-domain-policy.dtd"> <cross-domain-policy> <site-control permitted-cross-domain-policies="master-only"/> <allow-access-from domain="*" to-ports="4000" /> </cross-domain-policy>
Per maggiori descrizioni sulla sintassi del file è sufficiente appoggiarsi al sito dell’Adobe, ai fini di questo articolo basti sapere che comunque questo specifico file segnala al flash player di accettare una connessione TCP sulla porta 4000 proveniente da un qualunque indirizzo IP. Il vero problema di gestire questo file è disporre di un software che fornisca la policy in risposta ad una specifica richiesta. Nelle mie ricerche ho trovato pochi esempi compilati sommariamente e quindi ho preferito disporne uno in autonomia usando il linguaggio C per garantire la massima flessibilità e una buona portabilità:
/*
----------------------------------------
MUDflash_policy 02.02.2010
----------------------------------------
Server in ascolto su una porta specifica
che rimane in attesa di connessioni per
inviare una stringa di dati ad un client
richiedente.
----------------------------------------
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <netinet/in.h>
#define VERSIONE "0.1"
#define SERVER_PORT 4003
int main(int argc, char *argv[]) {
struct sockaddr_in srv_addr; // indirizzo del server
struct sockaddr_in client_addr; // indirizzo del client
int client_len = sizeof(client_addr); // dimensione dell'indirizzo del client
int listen_sd; // descrittore in ascolto - canale pubblico
int accept_sd; // descrittore in connessione - canale privato
int r = -1; // valore di ritorno da funzione
char buffer[1024] = ""; // buffer in ricezione e stringa da spedire
int n = 0; // numero di caratteri da spedire al client
/* Visualizza il messaggio di presentazione */
printf("\r\n");
printf("MUDflash_policy, versione %s\r\n", VERSIONE);
printf("-----------------------------\r\n");
/* Crea un sd in ascolto */
listen_sd = socket(AF_INET, SOCK_STREAM, 0);
if (listen_sd < 0) {
perror("MUDflash_policy - socket()");
exit(-1);
}
/* Collega il socket alla porta specificata */
memset(&srv_addr, 0, sizeof(srv_addr));
srv_addr.sin_family = AF_INET;
srv_addr.sin_addr.s_addr = htonl(INADDR_ANY);
srv_addr.sin_port = htons(SERVER_PORT);
r = bind(listen_sd, (struct sockaddr *)&srv_addr, sizeof(srv_addr));
if (r < 0) {
perror("MUDflash_policy - bind()");
close(listen_sd);
exit(-1);
}
/* Apri il canale pubblico */
r = listen(listen_sd, 5);
if (r < 0) {
perror("MUDflash_policy - listen()");
close(listen_sd);
exit(-1);
}
printf("Server avviato, in attesa di connesioni sulla porta %d.\n", SERVER_PORT);
/* Avvia l'ascolto per connessioni entranti */
for (;
{
accept_sd = accept(listen_sd,(struct sockaddr*) &client_addr, &client_len);
if (accept_sd < 0) {
perror("MUDflash_policy - accept()");
close(listen_sd);
exit(-1);
}
/* Un client si e' connesso (accept sbloccata) */
printf("*** Connessione di un client avvenuta ***\r\n");
/* Ricevi un messaggio dal client */
sprintf(buffer, ""); // svuota il buffer prima che si accodino msg di connessioni precedenti e degeneri in overflow...
r = recv(accept_sd, buffer, sizeof(buffer), 0);
if (r <= 0) {
perror("MUDflash_policy - recv()");
close(listen_sd);
close(accept_sd);
exit(-1);
}
printf("Messaggio ricevuto: \"%s\".\r\n", buffer);
/* Invia la policy al client */
strcpy(buffer, "<?xml version='1.0'?>\n<!DOCTYPE cross-domain-policy SYSTEM");
strcat(buffer, "'/xml/dtds/cross-domain-policy.dtd'><cross-domain-policy>\n");
strcat(buffer, "<site-control permitted-cross-domain-policies='all'/>\n");
strcat(buffer, "<allow-access-from domain='*' to-ports='4000' />\n");
strcat(buffer, "</cross-domain-policy>\n");
n = strlen(buffer);
r = send(accept_sd, buffer, n, 0);
if (r <= 0) {
perror("MUDflash_policy - send()");
close(listen_sd);
close(accept_sd);
exit(-1);
}
printf("Invio della Policy al client...OK\r\n");
/* chiudi il canale privato */
close(accept_sd);
printf("Chiusura della connessione con il client.\r\n");
}
/* chiudi il canale pubblico */
close(listen_sd);
}
/* EoF */
