B.2 Programac~ao de Aplicac~oes com a API do S3L
B.2.8 Metodologia e Exemplos de Utilizac~ao da API do S3L
Nesta secc~ao sugere{se uma metodologia generica a seguir na programac~ao de aplicac~oes com as funcionalidades oferecidas pela API do S3L. Os passos a seguir nas variantes ponto- -a{ponto e multiponto do S3L s~ao semelhantes. Todavia, existem diferencas sucientes que justicam uma apresentac~ao separada. A metodologia apresentada e consubstanciada com exemplos comentados do tipo cliente{servidor.
S3L Ponto{a{Ponto
As etapas envolvidas na utilizac~ao das funcionalidades ponto{a{ponto da API do S3L s~ao, fundamentalmente, as seguintes:
tarefas do produtor de mensagens S3L ponto{a{ponto:
1. obtenc~ao de informac~ao que identica e caracteriza a entidade produtora; 2. inicializac~ao de um contexto S3L ponto{a{ponto, especicando a entidade des-
tino da mensagem e as qualidades de servico pretendidas;
3. assemblagem da mensagem S3L ponto{a{ponto, com base no contexto seguro denido;
4. envio pela rede, utilizando as func~oes de escrita sobre sockets providenciadas pelo S3L; alternativamente, outras formas de transmiss~ao poder~ao ser empre- gues, como por exemplo o armazenamento em memoria secundaria tendo em vista a posterior \entrega manual" ao destinatario;
5. repetic~ao das etapas 2, 3 e 4, com possvel reutilizac~ao dos contextos produzidos na etapa 2;
tarefas do consumidor de mensagens S3L ponto{a{ponto:
1. obtenc~ao de informac~ao que identica e caracteriza a entidade consumidora; 2. inicializac~ao de um contexto S3L ponto{a{ponto, preparando{o para acolher a
informac~ao contextual produzida pela analise de uma mensagem S3L ponto{a- -ponto recebida;
3. recepc~ao de uma mensagem S3L ponto{a{ponto a partir da rede com base nas func~oes de leitura sobresocketsprovidenciadas pelo S3L, ou obtenc~ao da men- sagem atraves de outros meios,c.f. o seu metodo original de armazenamento e distribuic~ao (e.g., leitura de um cheiro);
4. processamento da mensagem S3L ponto{a{ponto, da qual resulta a recuperac~ao dos dados e o preenchimento do contexto S3L ponto{a{ponto previamente ini- cializado;
5. repetic~ao das etapas 3 e 4, com possvel reutilizac~ao do mesmo contexto (a etapa 2 dispensa{se porque o contexto de recepc~ao e automaticamente sobreposto se for reutilizado).
A gura B.6 encerra o codigo C relativo a um produtor de mensagens S3L ponto{a- -ponto. As linhas de codigo mais relevantes, em termos de funcionalidades proprias do S3L s~ao, de seguida, comentadas:
linha 1: inclus~ao do cheiro s3lsocket.h, que dene a interface de acesso as fun- cionalidades S3L (e tambem as funcionalidades normais sobresocketsBerkeley, pelo que se dispensa a inclus~ao explcita das interfaces especcas para esse efeito); linha 6: declarac~ao de uma estrutura personal infodo tipo S3LPartieInfoonde
sera preservada informac~ao especca do produtor;
linha 7: declarac~ao de uma estrutura do tipo S3LCtxdestinada a denic~ao de con- textos S3L ponto{a{ponto;
1 #include "s3lsocket.h" 2 #define MENSAGEM "Ola mundo!" 3 4 main() 5 { 6 S3LPartieInfo personal_info; 7 S3LCtx ctx; 8 S3Lbool skeyx_called=S3LFALSE;
9 int ret, sockfd;
10 struct sockaddr_in srvaddrin; 11
12 /******* etapa 1: obtencao de informacao pessoal guardada no PSE *******/ 13 S3Linit_S3LPartieInfo(&personal_info);
14 if (S3Lfill_S3LPartieInfo(&personal_info)!=S3LTRUE)
15 exit(1);
16
17 /******* etapa 2: inicializacao e preenchimento do contexto S3L *******/ 18 S3Linit_S3LCtx(&ctx, &personal_info);
19 if ((ret=S3Lmake_S3LCtx (&ctx, "C=PT, CN=ruf, D=user", NSID_X500, 0L 20 "DES-CBC", "IDEA", "IDEA", "NO_Z", 21 "193.136.8.7", &skeyx_called))!=S3LTRUE)
22 exit(1);
23
24 /* procedimentos usuais de instalacao de um cliente TCP */ 25 26 if ((sockfd=socket(AF_INET, SOCK_STREAM, 0))<0) 27 exit(1); 28 29 bzero(&srvaddrin, sizeof(srvaddrin)); 30 srvaddrin.sin_family = AF_INET; 31 srvaddrin.sin_addr.s_addr = inet_addr("193.136.8.7"); 32 srvaddrin.sin_port = htons(55555); 33
34 if (connect(sockfd, (struct sockaddr *) &srvaddrin, sizeof(srvaddrin)) < 0)
35 exit(1);
36
37 /******* etapas 3 e 4 : assemblagem e envio da mensagem S3L *******/ 38 ret=S3Lwrite(sockfd, MENSAGEM, strlen(MENSAGEM)+1, &ctx);
39
40 /******* eventual repeticao das etapas 2 (so preenchimento), 3 e 4 *******/ 41
42 /******* devolucao de memoria dinamica na saida *******/ 43 S3Lfree_S3LPartieInfo(&personal_info);
44 S3Lfree_S3LCtx(&ctx); 45 close(sockfd);
46 exit(0);
47 }
Figura B.6: Exemplo de um produtor de mensagens S3L ponto{a{ponto.
linha 8: declarac~ao de uma variavel booleana cujo valor logico representa a ocorr^encia previa (no contexto deste produtor), implcita ou explcita, do protocolo Skeyx; por motivos obvios, a variavel e inicializada a S3LFALSE; a variavel sera um dos
linha 13: inicializac~ao da estrutura personal info, preparando{a para posterior preenchimento;
linha 14: preenchimento da estrutura personal info, pela consulta de varios ele- mentos de informac~ao \pessoal" preservados no PSE do produtor; para o efeito, sera pedida a introduc~ao de um PIN, pelo que e conveniente que a invocac~ao de
S3Lfill S3LPartieInfose faca o mais cedo possvel, como e o caso do exemplo em
quest~ao;
linha 18: inicializac~ao da estrutura ctxtendo em vista uma posterior denic~ao; linhas 19, 20 e 21: denic~ao do contexto S3L ponto{a{ponto, com base no qual
sera gerada uma ou mais mensagens S3L ponto{a{ponto no produtor; no caso pre- sente, \C=PT, CN=ruf, D=user" e o nome distinto X.500 do destino (consumidor), NSID X500indica que se usou o nome distinto (e n~ao a sua sntese MD5) para iden-
ticar o destino, 0L e o valor de (ou seja, n~ao se pede a detecc~ao de ataques{de- -repetic~ao),DES-CBC identica o algoritmo simetrico do tipo CBC com base no qual
Kp sera cifrado, IDEA (1a ocorr^encia) dene o algoritmo com base no qual a men- sagem do utilizador sera cifrada,IDEA(2a ocorr^encia) dene o algoritmo a usar em conjunc~ao com o MD5 para produzir o MAC, NO Z signica que n~ao se pretende
compress~ao dos dados, 193.136.8.7e o endereco IP do destinatario (util caso se-
ja necessario executar Skeyx implicitamente) e skeyx called controla e re ecte a
ocorr^encia do protocolo Skeyx no interior deS3Lmake S3LCtx(se forS3LTRUE, ent~ao
o protocolo Skeyx foi executado recentemente com o consumidor e portanto n~ao de- ve ser executado novamente; caso contrario, indica que, em caso de necessidade, o protocolo Skeyx deve ser executado);
linha 38: envio da mensagem MENSAGEM com base no contexto S3L ponto{a{ponto
ctx;
linhas 43 e 44: devoluc~ao da memoria din^amica reservada durante a inicializac~ao ou preenchimento das estruturaspersonal info ectx.
As tarefas mais importantes correspondem, precisamente, as etapas apresentadas no incio desta secc~ao para um produtor de mensagens S3L ponto{a{ponto.
A gura B.7 apresenta o codigo C do consumidor de mensagens S3L ponto{a{ponto correspondente ao produtor da gura B.6. Seguem{se alguns comentarios relativos ao codigo do consumidor:
linhas 1, 5, 6, 12, 13, e 17: semelhantes as linhas de codigo com o mesmo conteudo, no produtor (ver a gura B.6); saliente{se que, relativamente ao contexto ctx ha
agora apenas lugar a sua inicializac~ao (linha 17), uma vez que o seu preenchimento e feito, automaticamente, durante a analise de uma mensagem S3L ponto{a{ponto recebida (ver linha 39);
1 #include "s3lsocket.h" 2 3 main() 4 { 5 S3LPartieInfo personal_info; 6 S3LCtx ctx;
7 int sockfd, newsockfd, ret;
8 struct sockaddr_in srvaddrin;
9 char buf[1024];
10
11 /******* etapa 1: obtencao de informacao pessoal guardada no PSE *******/ 12 S3Linit_S3LPartieInfo(&personal_info);
13 if (S3Lfill_S3LPartieInfo(&personal_info)!=S3LTRUE)
14 exit(1);
15
16 /******* etapa 2: inicializacao do contexto S3L *******/ 17 S3Linit_S3LCtx(&ctx, &personal_info);
18
19 /* procedimentos usuais de instalacao de um servidor TCP */ 20 if ((sockfd=socket(AF_INET, SOCK_STREAM, 0))<0) 21 exit(1); 22 23 bzero(&srvaddrin, sizeof(srvaddrin)); 24 srvaddrin.sin_family = AF_INET; 25 srvaddrin.sin_addr.s_addr = htonl(INADDR_ANY); 26 srvaddrin.sin_port = htons(55555); 27
28 if(bind(sockfd, (struct sockaddr *) &srvaddrin, sizeof(srvaddrin)) < 0)
29 exit(1); 30 31 if (listen(sockfd, 5)) 32 exit(1); 33 34 if ((newsockfd=accept(sockfd, 0, 0)) < 0) 35 exit(1); 36
37 /******* etapas 3 e 4: recepcao e desassemblagem da mensagem S3L 38 com actualizacao do contexto ctx ******/
39 ret=S3Lread(newsockfd, buf, 1024, &ctx); 40
41 /******* etapa 5: eventual repeticao das etapas 3 e 4 apos novo accept */ 42
43 /******* devolucao de memoria dinamica (`a saida) *******/ 44 S3Lfree_S3LPartieInfo(&personal_info);
45 S3Lfree_S3LCtx(&ctx);
46 close(newsockfd); close(sockfd);
47 exit(0);
48 }
Figura B.7: Exemplo de um consumidor de mensagens S3L ponto{a{ponto. linha 39: leitura de uma mensagem S3L ponto{a{ponto da rede e seu processamento,
da resultando a obtenc~ao dos dados encapsulados na mensagem e a denic~ao do contexto S3L ponto{a{ponto correspondente as qualidades de servico especicadas
pelo originador da mensagem; caso o consumidor assuma, de seguida, o papel de produtor de mensagens, este contexto recem denido podera ser reutilizado se o destino dessas mensagens for o originador que deniu, em primeira inst^ancia, esse contexto;
linha 41: possvel recepc~ao de novas mensagens S3L ponto{a{ponto (via S3Lread,
S3Lrecv, etc.) com eventual reutilizac~ao do mesmo contextoctxsem necessidade de
reinicializa{lo (os antigos valores dos seus campos do contexto s~ao automaticamente sobrepostos pelos novos);
linhas 44 e 45: devoluc~ao da memoria din^amica reservada durante a inicializac~ao ou preenchimento das estruturaspersonal info ectx.
S3L Multiponto
A utilizac~ao das funcionalidades proporcionadas pelas extens~oes multiponto do S3L segue um roteiro bem denido, que se divide em dois conjunto de tarefas, em func~ao do papel a desempenhar:
tarefas do produtor de mensagens S3L multiponto:
1. obtenc~ao de informac~ao que identica e caracteriza a entidade produtora; 2. inicializac~ao de um contexto S3L multiponto, especicando{se o endereco IP
Multicast do grupo e identicando{se o seu dono;
3. assemblagem da mensagem S3L multiponto com base no contexto inicializado em 2 (e que acaba por ser completamente denido, em resultado de uma junc~ao implcita junto do dono do grupo S3L);
4. envio da mensagem assemblada para o grupo S3L, subgrupo de um determinado grupoIP Multicast, atraves da func~ao S3Lsendto;
5. repetic~ao das etapas 2, 3 e 4, com possvel reutilizac~ao dos contextos iniciali- zados na etapa 2 sempre que o grupo em causa e o seu dono se mantenham os mesmos;
tarefas do consumidor de mensagens S3L multiponto:
1. obtenc~ao de informac~ao que identica e caracteriza a entidade consumidora; 2. inicializac~ao de um contexto S3L multiponto, especicando{se o endereco IP
Multicast do grupo e identicando{se o seu dono;
3. junc~ao explcita de umsocket Berkeley ao grupoIP Multicast 7; 4. recepc~ao de uma mensagem S3L multiponto viaS3Lrecvfrom;
5. processamento da mensagem recebida com base no contexto inicializado em 2 (e que acaba por ser completamente denido, em resultado de uma junc~ao implcita junto do dono do grupo S3L);
6. repetic~ao das etapas 2, 3, 4 e 5, com possvel reutilizac~ao dos contextos inicia- lizados na etapa 2 sempre que o grupo em causa e o seu dono se mantenham os mesmos, em cujo caso se dispensa tambem a repetic~ao da junc~aoIP Multicast efectuada em 3.
A gura B.8 apresenta o codigo de um produtor de mensagens S3L multiponto. Se- guem{se alguns comentarios sobre as linhas de codigo extra relativamente a um \produtor de Berkeley":
linha 1: inclus~ao do cheiro s3lsocket.h, que dene a interface de acesso as fun- cionalidades S3L (e tambem as funcionalidades normais sobresocketsBerkeley, pelo que se dispensa a inclus~ao explcita das interfaces especcas para esse efeito); linha 4: declarac~ao de uma estrutura personal info do tipo S3LPartieInfoonde
sera preservada informac~ao especca do produtor;
linha 5: declarac~ao de uma estrutura do tipo S3LMCtx destinada a denic~ao de contextos S3L multiponto;
linha 13: inicializac~ao da estrutura personal info, preparando{a para posterior preenchimento;
linha 14: preenchimento da estrutura personal info, pela consulta de varios ele- mentos de informac~ao \pessoal" preservados no PSE do produtor; para o efeito, sera pedida a introduc~ao de um PIN, pelo que e conveniente que a invocac~ao de
S3Lfill S3LPartieInfose faca o mais cedo possvel, como e o caso do exemplo em
quest~ao;
linhas 18 a 20: inicializac~ao da estruturamctxtendo em vista a sua denic~ao comple- ta, atraves do processo de junc~ao ao grupo, a ocorrer, posteriormente, de forma im- plcita (linha 37); para alem da \informac~ao pessoal" do produtor (personal info),
obtida na linha 14, indica{se o grupo IP Multicast (235.0.0.0), o nome distinto do dono do subgrupo S3L (C=PT, CN=ruf, D=user) bem como a sua localizac~ao
(193.136.8.7); na linha 20, a inicializac~ao do campo delta a zero (0L) indica que
n~ao se pretende detecc~ao de ataques{de{repetic~ao com base num tempo de vida das mensagens, dado pordelta;
linhas 37 e 38: a mensagem produzida na linha 32 e convertida numa mensagem S3L multiponto e enviada para o subgrupo S3L cujo dono foi denido na linha 18; na primeira iterac~ao do ciclo, ocorrera o processo de junc~ao junto do dono do subgrupo S3L, o que permitira completar a denic~ao do contexto S3L multiponto
mctx, apos o que a mensagem S3L e assemblada e enviada para o endereco IP Multicast 235.0.0.0; nas proximas iterac~oes do ciclo, poder~ao ocorrer rejunc~oes ao subgrupo S3L, desde que a chave{do{grupo (GIK) seja efemera e o seu tempo de vida tenha, entretanto, expirado; a variavel de contexto mctxe sucessivamente
reutilizada;
linha 45: exemplica a devoluc~ao da memoria din^amica reservada durante a de- nic~ao da estrutura personal info na linha 14 e ctx; obviamente, esta linha n~ao e
1 #include "s3lsocket.h" 2 main()
3 {
4 S3LPartieInfo personal_info;
5 S3LMCtx mctx;
6 struct sockaddr_in addr;
7 int sockfd;
8 struct ip_mreq mreq;
9 time_t tempo;
10 char buf[1024];
11
12 /******* etapa 1: obtencao de informacao pessoal guardada no PSE */ 13 S3Linit_S3LPartieInfo(&personal_info);
14 if (S3Lfill_S3LPartieInfo(&personal_info)!=S3LTRUE)
15 exit(1);
16
17 /******* etapa 2: inicializacao do contexto S3L multiponto */
18 S3LMinit_S3LMCtx(&mctx, &personal_info, "235.0.0.0", "C=PT, CN=ruf, D=user",
19 "193.136.8.7");
20 mctx.delta=0L; 21
22 /* procedimentos usuais de instalacao de um servidor IP multicast */ 23 if ((sockfd=socket(AF_INET, SOCK_DGRAM,0))<0) 24 exit(1); 25 bzero(&addr, sizeof(addr)); 26 addr.sin_family = AF_INET; 27 addr.sin_port = htons(55555); 28 addr.sin_addr.s_addr = inet_addr("235.0.0.0"); 29 30 while (1) { 31 tempo=time(0);
32 sprintf(buf, "tempo local no produtor : %s", ctime(&tempo)); 33
34 /******* etapas 3, 4 e 5: assemblagem e envio da mensagem S3L 35 multiponto com actualizacao implicita do contexto mctx que
36 sera reutilizado dentro deste ciclo */
37 if ((S3Lsendto(sockfd, buf, strlen(buf)+1, 0, (struct sockaddr *)&addr,
38 sizeof(addr), &mctx))<=0) 39 exit(1); 40 41 sleep(5); 42 } 43
44 /******* devolucao de memoria dinamica (`a saida) *******/ 45 S3Lfree_S3LPartieInfo(&personal_info);
46 close(sockfd);
47 exit(0);
48 }
Figura B.8: Exemplo de um produtor S3L multiponto.
A gura B.9 apresenta o codigo C relativo ao consumidor de mensagens S3L multiponto correspondente ao produtor da gura B.8. Seguem{se alguns comentarios relativos ao seu codigo:
1 #include "s3lsocket.h" 2 3 main() 4 { 5 S3LPartieInfo personal_info; 6 S3LMCtx mctx;
7 struct sockaddr_in addr;
8 int addrlen, sockfd;
9 struct ip_mreq mreq;
10 int share;
11 char buf[1024];
12
13 /******* etapa 1: obtencao de informacao pessoal guardada no PSE */ 14 S3Linit_S3LPartieInfo(&personal_info);
15 if (S3Lfill_S3LPartieInfo(&personal_info)!=S3LTRUE)
16 exit(1);
17
18 /******* etapa 2: inicializacao do contexto S3L multiponto */
19 S3LMinit_S3LMCtx(&mctx, &personal_info, "235.0.0.0", "C=PT, CN=ruf, D=user",
20 "193.136.8.7");
21
22 /* procedimentos usuais de instalacao de um cliente IP multicast */ 23 if ((sockfd=socket(AF_INET, SOCK_DGRAM,0))<0) 24 exit(1); 25 26 bzero(&addr, sizeof(addr)); 27 addr.sin_family = AF_INET; 28 addr.sin_port = htons(55555); 29 addr.sin_addr.s_addr = inet_addr("235.0.0.0"); 30 addrlen=sizeof(addr); 31
32 /* partilha do porto usado (55555) com outros processos */
33 share=1;
34 if (setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, (const char *)&share,
35 sizeof(share))<0)
36 exit(1);
37
38 if (bind(sockfd, (struct sockaddr*)&addr, sizeof(addr))<0)
39 exit(1);
40
41 /******* etapa 3: juncao explicita ao grupo IP multicast 235.0.0.0 */ 42 mreq.imr_multiaddr.s_addr = inet_addr("235.0.0.0");
43 mreq.imr_interface.s_addr = htonl(INADDR_ANY);
44 if (setsockopt(sockfd, IPPROTO_IP, IP_ADD_MEMBERSHIP, (const char*)&mreq,
45 sizeof(mreq))<0) 46 exit(1); 47 48 while(1) { 49 bzero(buf, SBUF_SIZE); 50 addrlen=sizeof(addr); 51
52 /******* etapas 4, 5 e 6: recepcao e desassemblagem da mensagem S3L 53 multiponto com actualizacao implicita do contexto mctx que
54 sera reutilizado dentro deste ciclo */
55 if (S3Lrecvfrom(sockfd, buf, SBUF_SIZE, 0, (struct sockaddr *)&addr,