UNIVERSIDADE REGIONAL DE BLUMENAU CENTRO DE CIÊNCIAS EXATAS E NATURAIS CURSO DE SISTEMAS DE INFORMAÇÃO – BACHARELADO SISTEMA PARA CORREÇÃO AUTOMÁTICA DE QUESTÕES NAS PROVAS DE CONCURSOS DE PROGRAMAÇÃO MARCOS KIRCHNER BLUMENAU 2004 2004/II-08 MARCOS KIRCHNER SISTEMA PARA CORREÇÃO AUTOMÁTICA DE QUESTÕES NAS PROVAS DE CONCURSOS DE PROGRAMAÇÃO Trabalho de Conclusão de Curso submetido à Universidade Regional de Blumenau para a obtenção dos créditos na disciplina Trabalho de Conclusão de Curso II do curso de Sistemas de Informação – Bacharelado. Prof. Jomi Fred Hübner – Orientador BLUMENAU 2004 2004/II-08 SISTEMA PARA CORREÇÃO AUTOMÁTICA DE QUESTÕES NAS PROVAS DE CONCURSOS DE PROGRAMAÇÃO Por MARCOS KIRCHNER Trabalho aprovado para obtenção dos créditos na disciplina de Trabalho de Conclusão de Curso II, pela banca examinadora formada por: Presidente: Prof. Jomi Fred Hübner – Orientador, FURB Membro: Prof. Roberto Heinzle, FURB Membro: Prof. Alexander Roberto Valdameri, FURB BLUMENAU 2004 AGRADECIMENTOS Agradeço ao professor Jomi pela paciência quando eu resolvi mudar o tema do meu trabalho, pela colaboração neste trabalho e por ter recomandado o uso do LATEX para escrever esse texto. Aos meus pais que me ensinaram ou possibilitaram que eu aprendesse tudo que sei hoje. À todos que de alguma forma contribuı́ram com a realização deste. RESUMO Este trabalho apresenta um sistema de correção automatizada a ser utilizado em provas de concursos de programação. Um sistema desse gênero deve prover um ambiente seguro para executar código arbitrário enviado por qualquer programador, sem comprometer as informações confidenciais e a estabilidade do sistema. O sistema foi implementado em linguagem C#.NET e corrige programas nessa mesma linguagem, mas foi projetado o intuito de adição de módulos para outras linguagens. Palavras Chave: Competições de programação, Ambiente de execução seguro, Sistema de correção automatizada. ABSTRACT This work presents an online judge system to be used in programming contests. Such a system must provide a secure execution environment that can execute arbitrary code submitted by any programmer, without compromising confidential informations or system stability. This system’s been implemented in C#.NET language and can judge programs written in this same language, but has been projected with extensibility for new programming languages in mind. Key-Words: Programming contests, Secure execution environment, Online judge. LISTA DE ILUSTRAÇÕES Figura 2.1 – Interação do .NET Framework com os componentes do sistema operacional. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21 Figura 2.2 – Estrutura de uma assembly. . . . . . . . . . . . . . . . . . . . . . 23 Figura 2.3 – Visão simplificada da segurança de acesso do código. . . . . . . . . 26 Figura 2.4 – Grupos de código de um nı́vel da polı́tica de segurança. . . . . . . 27 Figura 2.5 – Interação dos componentes durante uma requisição de inı́cio e finalização de um serviço. . . . . . . . . . . . . . . . . . . . . . . . 32 Figura 3.1 – Diagrama de casos de uso do sistema web. . . . . . . . . . . . . . . 36 Figura 3.2 – Diagrama de casos de uso do sistema de correção. . . . . . . . . . 37 Figura 3.3 – Componentes do sistema. . . . . . . . . . . . . . . . . . . . . . . . 37 Figura 3.4 – Diagrama de classes do componente Model. . . . . . . . . . . . . . 39 Figura 3.5 – Diagrama de classes do componente ReportModel. . . . . . . . . . 40 Figura 3.6 – Diagrama de classes do componente IDAL. . . . . . . . . . . . . . 41 Figura 3.7 – Modelo conceitual do banco de dados. . . . . . . . . . . . . . . . . 42 Figura 3.8 – Diagrama de classes do componente DALFactory. . . . . . . . . . 43 Figura 3.9 – Diagrama de classes do componente BLL. . . . . . . . . . . . . . . 44 Figura 3.10 – Diagrama de navegação do sistema web. . . . . . . . . . . . . . . . 45 Figura 3.11 – Interação dos componentes com o sistema web durante o envio de uma solução. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 46 Figura 3.12 – Diagrama de classes do componente JudgeServer. . . . . . . . . . 48 Figura 3.13 – Interação dos componentes do sistema de correção durante a correção de uma solução. . . . . . . . . . . . . . . . . . . . . . . . 49 Figura 3.14 – Relação entre os processos e os Application Domains do sistema de correção e do Wrapper. . . . . . . . . . . . . . . . . . . . . . . 56 Figura 3.15 – Tela de cadastro de categorias. . . . . . . . . . . . . . . . . . . . . 59 Figura 3.16 – Tela de cadastro de problemas. . . . . . . . . . . . . . . . . . . . . 60 Figura 3.17 – Tela para indicação das categorias dos problemas. . . . . . . . . . 60 Figura 3.18 – Tela de cadastro de conjuntos de entrada e saı́da para avaliação. . 61 Figura 3.19 – Tela de cadastro de categorias. . . . . . . . . . . . . . . . . . . . . 61 Figura 3.20 – Tela para indicação dos problemas de uma competição. . . . . . . 61 Figura 3.21 – Tela de cadastro de usuários. . . . . . . . . . . . . . . . . . . . . . 62 Figura 3.22 – Tela com a lista de categorias. . . . . . . . . . . . . . . . . . . . . 62 Figura 3.23 – Tela com a lista de problemas por categoria. . . . . . . . . . . . . 63 Figura 3.24 – Tela com os detalhes do problema. . . . . . . . . . . . . . . . . . . 63 Figura 3.25 – Tela com as competições. . . . . . . . . . . . . . . . . . . . . . . . 64 Figura 3.26 – Tela com os detalhes da competição. . . . . . . . . . . . . . . . . . 64 Figura 3.27 – Tela para submissão de programas. . . . . . . . . . . . . . . . . . 65 Figura 3.28 – Tela com a lista das últimas submissões. . . . . . . . . . . . . . . 65 Figura 3.29 – Resultados do sistema de correção para os dois programas maliciosos submetidos a correção. . . . . . . . . . . . . . . . . . . . . . . 67 Figura 3.30 – Tela com as estatı́sticas dos problemas. . . . . . . . . . . . . . . . 67 Figura 3.31 – Tela com ranking de autores. . . . . . . . . . . . . . . . . . . . . . 67 LISTA DE QUADROS 2.1 Exemplo de uso de segurança baseada em funções. . . . . . . . . . . . . . . 24 3.1 Procedimento armazenado para listar as competições de um usuário. . . . . 51 3.2 Código para chamar o procedimento armazenado ContestsListByUser. . . . 52 3.3 Atributos e propriedades da classe CountryInfo. . . . . . . . . . . . . . . . 53 3.4 Configuração de segurança para a área restrita ao administrador do sistema web. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 53 3.5 Código para autenticação do usuário no sistema web. . . . . . . . . . . . . 54 3.6 Código do serviço do Windows. . . . . . . . . . . . . . . . . . . . . . . . . 54 3.7 Código do método Submission.SignalJudge() do componente BLL. . . . . . 55 3.8 Atributo para identificação do programa submetido para correção. . . . . . 56 3.9 Rotina principal do programa Wrapper. . . . . . . . . . . . . . . . . . . . . 57 3.10 Rotina CreateAppDomain() do programa Wrapper. . . . . . . . . . . . . . 58 3.11 Programa malicioso que consome muito tempo de CPU. . . . . . . . . . . . 66 3.12 Programa malicioso que tenta acessar o disco. . . . . . . . . . . . . . . . . 66 LISTA DE TABELAS 3.1 Requisitos funcionais do sistema . . . . . . . . . . . . . . . . . . . . . . . . 34 3.2 Requisitos não funcionais do sistema . . . . . . . . . . . . . . . . . . . . . 35 LISTA DE ABREVIATURAS ACM Association for Computing Machinery ACM ICPC Association for Computing Machinery (ACM) International Collegiate Programming Contest API Application Programming Interfaces ASP Active Server Pages CLR Common Language Runtime COM Component Object Model CSS Cascading Style Sheets DAAB Data Access Application Block DAL Data Access Logic DNS Domain Name System DOM Document Object Model GAC Global Assembly Cache GUID Globally Unique Identifier HTML Hypertext Markup Language HTTP Hypertext Transport Protocol IDE Integrated Development Environment IIS Internet Information Services IOI International Olympiad in Informatics JIT just-in-time MER Modelo Entidade-Relacionamento MSIL Microsoft Intermediate Language MVC Model-View-Controler PHP PHP: Hypertext Preprocessor SCM Service Control Manager SDK Software Development Kit SGBD Sistema Gerenciador de Banco de Dados SP Stored Procedure SQL Structured Query Language TI Tecnologia da Informação UML Unified Modeling Language URL Uniform Resource Locator W3C World Wide Web Consortium XHTML Extensible Hypertext Markup Language XML Extensible Markup Language SUMÁRIO 1 Introdução 16 1.1 Objetivos do trabalho . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17 1.2 Estrutura do trabalho . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18 2 Fundamentação teórica 2.1 19 Competições de programação . . . . . . . . . . . . . . . . . . . . . . . . . . . 19 2.2 .NET Framework . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20 2.2.1 Segurança de aplicações .NET . . . . . . . . . . . . . . . . . . . . . . . . . . 23 2.2.2 ASP.NET . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27 2.2.3 Serviços do Windows . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 30 2.3 Web standards . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31 2.4 Trabalhos correlatos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 33 3 Desenvolvimento do sistema 3.1 3.1.1 3.2 34 Requisitos principais do problema a ser trabalhado . . . . . . . . . . . . . . . 34 Diagramas de casos de uso . . . . . . . . . . . . . . . . . . . . . . . . . . . . 36 Especificação . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 36 3.2.1 Componente Model . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 38 3.2.2 Componente ReportModel . . . . . . . . . . . . . . . . . . . . . . . . . . . . 39 3.2.3 Componente IDAL . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 40 3.2.4 Componente DALFactory . . . . . . . . . . . . . . . . . . . . . . . . . . . . 42 3.2.5 Componente BLL . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 43 3.2.6 Componente Web . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 45 3.2.7 Componente JudgeServer . . . . . . . . . . . . . . . . . . . . . . . . . . . . 47 3.3 Implementação . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 50 3.3.1 Técnicas e ferramentas utilizadas . . . . . . . . . . . . . . . . . . . . . . . . 50 3.3.2 Banco de dados . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 51 3.3.3 Componentes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 52 3.3.4 Sistema web . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 52 3.3.5 Sistema de correção . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 54 3.3.6 Operacionalidade da implementação . . . . . . . . . . . . . . . . . . . . . . 59 3.4 3.4.1 Resultados e discussão . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 66 Dificuldades encontradas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 68 4 Conclusões 4.1 70 Extensões . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 70 Referências Bibliográficas 72 Apêndice A -- Cenários dos casos de uso do sistema web 74 A.1 Use Case ’Autenticação usuário’ . . . . . . . . . . . . . . . . . . . . . . . . . . 74 A.2 Use Case ’Cadastro de categorias’ . . . . . . . . . . . . . . . . . . . . . . . . . 74 A.3 Use Case ’Cadastro de problemas’ . . . . . . . . . . . . . . . . . . . . . . . . . 75 A.4 Use Case ’Cadastro usuário’ . . . . . . . . . . . . . . . . . . . . . . . . . . . . 75 A.5 Use Case ’Criar competições’ . . . . . . . . . . . . . . . . . . . . . . . . . . . 76 A.6 Use Case ’Enviar solução’ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 76 A.7 Use Case ’Inscrever em competição’ . . . . . . . . . . . . . . . . . . . . . . . . 77 A.8 Use Case ’Relatório de estatı́sticas dos problemas’ . . . . . . . . . . . . . . . . 77 A.9 Use Case ’Visualizar problema’ . . . . . . . . . . . . . . . . . . . . . . . . . . 77 A.10 Use Case ’Visualizar ranking autores’ . . . . . . . . . . . . . . . . . . . . . . . 78 A.11 Use Case ’Visualizar relatório submissões’ . . . . . . . . . . . . . . . . . . . . 78 Apêndice B -- Cenários dos casos de uso do sistema de correção 79 B.1 Use Case ’Corrigir programa’ . . . . . . . . . . . . . . . . . . . . . . . . . . . 79 Anexo A -- Permissões pré-definidas do .NET 81 16 1 INTRODUÇÃO Concursos de programação são competições organizadas por alguma entidade, onde várias equipes recebem um determinado número de problemas e devem resolvê-los escrevendo um programa. Há algumas boas razões para se participar desse tipo de concurso. As pessoas podem se divertir, ao mesmo tempo em que aprimoram suas habilidades de programação e aumentam as perspectivas de trabalhos. Além disso, alguns concursos como o TopCoder Challenge dão prêmios em dinheiro (SKIENA; REVILLA, 2003, p. 345). O número de participantes em concursos é elevado. Na competição da ACM de 2004, participaram 3150 times de 75 paı́ses e 73 times avançaram para as finais mundiais (ASSOCIATION FOR COMPUTING MACHINERY, 2004). Os times normalmente recebem vários problemas para serem solucionados e podem submeter um programa à correção várias vezes (passı́vel de punição para soluções incorretas). Durante as provas os times precisam de uma resposta rápida sobre a correção do programa, para aprimorar a implementação caso necessário, ou direcionar seus esforços para a solução de outro problema. Porém, é inviável para a equipe organizadora da competição receber e testar manualmente cada problema submetido. Para apresentar a resposta de uma submissão em tempo adequado, as competições normalmente fazem uso de sistemas de correção automatizados (juizes on-line). Segundo Manzoor (2004), a ACM utiliza um software chamado PC2 em suas competições. Esse tipo de software parece simples à primeira vista. Ele deve compilar o programa fonte submetido, carregar o arquivo executável e passar para o programa os dados de entrada. Assim que o programa finalizar, a saı́da do programa submetido deve ser comparada com a saı́da esperada, para determinar se o programa submetido resolveu a questão corretamente. No entanto, há riscos significantes associados à execução de código arbitrário: código malicioso pode danificar os recursos computacionais, roubar informações privativas, monitorar as atividades do usuário ou conseguir acesso para disparar ataques futuros (STONY BROOK UNIVERSITY, 2002). Conforme ressaltado por Stack, Eide e Lepreau (2003), o ambiente de execução deve ser seguro e robusto, não permitindo que um programa malicioso consuma excessivos recursos da máquina. Recursos principais incluem tempo de processador, memória, tempo de disco e utilização da rede. 1.1 Objetivos do trabalho 17 Além de serem utilizados em concursos de programação, alguns softwares desse tipo, a notar (UNIVERSIDAD DE VALLADOLID, [2004?]) e (URAL STATE UNIVERSITY, [2004?]) estão disponı́veis na Internet para que qualquer pessoa possa, a tı́tulo de aprimorar habilidades de programação, treinar para competições ou divertir-se, resolver problemas e submetê-los para correção. Os softwares conhecidos apresentam recursos de segurança para proteção contra código malicioso, e normalmente compilam e executam, com poucas restrições, programas escritos em C, C++, Java ou Pascal. Além disso, os softwares são criados para ambientes Unix / Linux. Não se tem conhecimento de implementação de um software similar que opere em ambiente Windows e/ou aceite submissão de programas escritos em linguagem C#. A proposta desse trabalho é a criação de um sistema de correção automatizada, com recursos de segurança similares aos sistemas existentes e que possa ser executado em ambiente Windows para compilação e execução de código escrito em C#. Ainda assim, o sistema deve apresentar uma arquitetura expansı́vel para que seja possı́vel adicionar capacidade de compilação e execução de código escrito em outras linguagens. Para gerenciamento do sistema de correção, propõe-se um sistema de informação em ambiente web que será responsável pela parte do gerenciamento de usuários, problemas disponı́veis para correção, competições e pela geração de relatórios diversos. 1.1 OBJETIVOS DO TRABALHO O objetivo deste trabalho é implementar um sistema que faça a correção automática de questões em provas de concursos de programação para programas escritos em linguagem C# .NET. Os objetivos especı́ficos do trabalho são: a) implementar um serviço do Windows que faça a correção das questões submetidas para avaliação; b) projetar uma arquitetura expansı́vel de forma que possam ser adicionados módulos para compilação de programas escritos em outras linguagens e a utilização de outros sistemas gerenciadores de banco de dados; c) criar um ambiente de execução seguro, onde se possa executar código arbitrário enviado por qualquer programador, sem comprometer a segurança e estabilidade do sistema e do computador; d) utilizar as opções de segurança fornecidas pelo .NET Framework; e) criar uma interface web para o sistema. 1.2 Estrutura do trabalho 18 1.2 ESTRUTURA DO TRABALHO O capı́tulo 2 apresenta a fundamentação teórica sobre competições de programação, .NET e web standards. O desenvolvimento do trabalho, incluindo requisitos, especificação, implementação de discussão dos resultados encontra-se no capı́tulo 3. O capı́tulo 4 apresenta as conclusões obtidas e sugere extensões do presente trabalho. 19 2 FUNDAMENTAÇÃO TEÓRICA Este capı́tulo apresenta fundamentação teórica pertinente ao tema de estudo do trabalho desenvolvido. A seção 2.1 apresenta de forma sucinta algumas competições de programação. A seção 2.2 versa sobre o .NET Framework e tecnologias afins, focando no aspecto de segurança que é fundamental para este trabalho (seção 2.2.1), e apresenta os conceitos do ASP.NET (seção 2.2.2) e serviços do Windows (seção 2.2.3). Segue-se uma seção sobre web standards, utilizado no desenvolvimento do sistema web deste trabalho (seção 2.3) e finaliza-se com uma seção sobre trabalhos correlatos (seção 2.4). 2.1 COMPETIÇÕES DE PROGRAMAÇÃO As três competições de programação mais importantes, segundo Skiena e Revilla (2003, p. 339), são a ACM International Collegiate Programming Contest (ACM ICPC), a International Olympiad in Informatics (IOI) e o TopCoder Challenge. A ACM ICPC é a maior competição de programação do mundo e é uma atividade da ACM que dá a oportunidade a alunos de faculdade de demonstrarem e aguçarem sua capacidade de resolver problemas e habilidades em computação (GUPTA, 2004). As equipes são formadas por três pessoas, e podem utilizar apenas um computador. A competição dura cinco horas e contém cerca de oito problemas. A equipe campeã é aquela que resolver corretamente o maior número de problemas. A IOI é uma competição para estudantes do ensino médio e seus objetivos são um tanto quanto diferentes dos da ACM ICPC. Os participantes desse evento normalmente não definiram a carreira que desejam seguir ainda. O evento procura estimular o interesse dos participantes na área de informática. Já o TopCoder Challenge é uma competição aberta a todos os programadores. A maior atração dessa competição são prêmios em dinheiro. Além disso, a companhia TopCoder usa as competições para identificar programadores promissores e fornece essas informações para seus clientes (SKIENA; REVILLA, 2003, p. 354). 2.2 .NET Framework 20 2.2 .NET FRAMEWORK O .NET Framework é, segundo Microsoft Corporation (2002b), uma das tecnologias centrais da plataforma .NET, e provê a estrutura de tempo de compilação e tempo de execução necessária para criar e executar aplicações baseadas em .NET. Microsoft Corporation (2004b) explica que o .NET é uma nova plataforma computacional que simplifica o desenvolvimento de aplicativos em ambientes distribuı́dos e que foi projetada para satisfazer os seguintes objetivos: a) prover um ambiente de programação orientado a objetos consistente, independente se o código é armazenado e executado localmente, executado localmente mas distribuı́do pela Internet ou executado remotamente; b) prover um ambiente de execução que minimiza os conflitos de distribuição e de versões de software; c) prover um ambiente de execução que garanta a execução segura de código; d) prover um ambiente de execução que elimine os problemas de desempenho de ambientes interpretados e linguagens de script; e) tornar a experiência do desenvolvedor consistente através dos vários tipos de aplicações, como aplicações baseadas em Windows e na web; f) utilizar padrões da indústria para todas as formas de comunicação, garantindo que código baseado no .NET Framework possa integrar com qualquer outro código. O .NET Framework tem dois componentes principais: o Common Language Runtime (CLR) e a biblioteca de classes (MICROSOFT CORPORATION, 2004b). O CLR gerencia o código em tempo de execução e provê os serviços principais, como gerenciamento de memória e de linhas de execução (Threads), compilação e outros serviços do sistema, além de promover a segurança e robustez do código. O código compilado para execução no CLR é chamado código gerenciado (Managed code), enquanto código que não executa no CLR é chamado código não-gerenciado (Unmanaged code). A biblioteca de classes é uma coleção de código pré-escrito para executar uma grande variedade de tarefas, incluindo exibir janelas e formulários, acessar os serviços básicos do Windows, ler e escrever em arquivos, acessar a rede e a Internet e acessar fontes de dados. A fig. 2.1 mostra a relação entre o CLR e a biblioteca de classes com as aplicações e com o sistema de um modo geral. Para que o CLR possa prover serviços ao código gerenciado, os compiladores devem 2.2 .NET Framework 21 emitir metadados, que descrevem os tipos, membros e referências no código. O metadados é armazenado juntamente com o código. O CLR utiliza o metadados para localizar e carregar classes, posicionar as instâncias dos objetos na memória, resolver as invocações de métodos, gerar código nativo, garantir a segurança e definir os limites do contexto de execução. Fonte: Microsoft Corporation (2004b). Figura 2.1 – Interação do .NET Framework com os componentes do sistema operacional. O processo de execução do código gerenciado engloba as seguintes etapas (MICROSOFT CORPORATION, 2004b): a) usar um compilador para converter o código-fonte em Microsoft Intermediate Language (MSIL), que é um conjunto de instruções independentes da arquitetura da CPU e que pode ser eficientemente convertido em código nativo. Quando um compilador produz código MSIL também é emitido o metadados; b) antes de ser executado, o código MSIL deve passar por um compilador just-intime (JIT) para ser convertido em código nativo, que é o código especifico para 2.2 .NET Framework 22 a arquitetura da CPU onde o programa e o compilador JIT estão executando. A compilação JIT leva em conta o fato de que alguma parte do código pode vir a não ser executada. Ao invés de converter todo o código MSIL em código nativo, a conversão é feita conforme necessidade e o código nativo resultante é armazenado na memória para chamadas subseqüentes. Antes de ser compilado em código nativo, o código MSIL deve passar por um processo de verificação, que examina o código MSIL e o metadados para descobrir se o código é type safe 1 . Durante a verificação há uma inspeção para determinar se o código MSIL foi gerado corretamente. Se a verificação determinar que o código não é type safe, uma exceção é gerada no momento da execução; c) depois de ter passado pelo processo de compilação JIT e geração de código nativo, o código pode ser executado. Cada método do programa deve passar pelo processo de compilação JIT na primeira vez que é invocado. O processo de compilação JIT e execução é repetido até que o programa seja finalizado. Durante a execução, o CLR provê serviços como identificação e destruição de objetos sem referências (Garbage collection), segurança, interoperabilidade com código nãogerenciado, suporte a depuração entre várias linguagens e um suporte avançado a distribuição e controle de versões. Conforme Robinson et al. (2001), o código MSIL resultante da compilação é armazenado em uma unidade lógica chama assembly. Uma assembly é auto-descritı́vel, e consiste do metadados que descreve a assembly, metadados que descrevem os tipos e métodos, código MSIL e recursos. Essas partes podem residir em um único arquivo ou espalhadas por vários arquivos. No caso de uma assembly com mais de um arquivo, o metadados que descreve a assembly contém referências para os demais arquivos, como ilustrado na fig. 2.2. Durante a execução, o CLR carrega as assemblies em um application domain. Application domains são uma unidade de processamento que o CLR emprega para prover isolamento entre as aplicações. Processos tem sido utilizados para isolar aplicações, sendo cada aplicação carregada em um processo separado (MICROSOFT CORPORATION, 2004b). Apesar de processos serem ideais para isolamento de aplicações, a comunicação e a troca de contexto entre processos é custosa em termos de desempenho. Robinson et al. (2001) explicam que o CLR divide um processo em múltiplos application domains, o que permite isolar os componentes sem o impacto de desempenho associado com a comunicação entre processos. 1 Código que acessa apenas as regiões de memória que é autorizado a acessar. 2.2 .NET Framework 23 Fonte: Robinson et al. (2001, p. 486–7). Figura 2.2 – Estrutura de uma assembly. 2.2.1 SEGURANÇA DE APLICAÇÕES .NET O .NET Framework oferece recursos de segurança de código e segurança de usuários que ajudam a lidar com as preocupações de segurança sobre código móvel (MICROSOFT CORPORATION, 2004b). Segundo Watkins e Lange (2002, tradução nossa), “Segurança baseada no código [. . . ] é um recurso fundamental para permitir segurança sobre código móvel. Código móvel pode ser acessado e executado por qualquer número de usuários, desconhecidos durante o desenvolvimento.”. As duas formas de segurança complementam uma a outra. Meier et al. (2003, tradução nossa) explica que a segurança de usuários responde a questão “Quem é o usuário e o que ele pode fazer?”enquanto que a segurança de código lida com “De onde vem o código, quem escreveu este código e o que o código pode fazer?”. A implementação de segurança de usuários no .NET Framework é chamada de segurança baseada em funções (Role-based security), e a segurança de código é chamada de segurança de acesso do código (Code access security). 2.2.1.1 SEGURANÇA BASEADA EM FUNÇÕES A segurança baseada em funções utiliza os conceitos de usuários e funções. Por exemplo, uma aplicação pode impor um valor limite para um caixa do banco processar uma 2.2 .NET Framework 24 transação, e permitir que o gerente processe transações de qualquer valor. A segurança baseada em funções é implementada utilizando-se os objetos Principal e Identity (MEIER et al., 2003). O objeto identity representa a identidade do usuário autenticado. O objeto principal representa o contexto de segurança da thread em execução, e contém um objeto identity e a definição das funções do usuário. O .NET Framework expõe um objeto chamado PrincipalPermission que permite especificar que uma classe/método só pode ser invocado por um usuário e/ou por uma função especı́ficos. O quadro 2.1 demonstra um exemplo de uma classe que só pode ser chamada por usuários que façam parte da função “Managers”. [PrincipalPermission(SecurityAction.Demand, Role="Managers")] public sealed class OnlyManagersCanCallMe { } Fonte: Meier et al. (2003). Quadro 2.1 – Exemplo de uso de segurança baseada em funções. 2.2.1.2 SEGURANÇA DE ACESSO DO CÓDIGO Segurança de acesso do código é um recurso do .NET Framework que gerencia o código dependendo do nı́vel de confiança no mesmo. O CLR começa a executar o código de uma assembly apenas se ele confiar no código o suficiente para permitir sua execução. Se o código não for confiável o suficiente para ser executado, ou se for executado mas tentar executar uma operação para o qual não tem privilégios, uma exceção é gerada (ROBINSON et al., 2001). Segundo Meier et al. (2003), a segurança de acesso do código consiste dos seguintes elementos: a) código: todo código gerenciado está sujeito às polı́ticas de segurança de acesso do código. Quando uma assembly é carregada, recebe um conjunto de permissões que determinam que tipo de recursos pode acessar e quais operações privilegiadas pode executar. O sistema de segurança usa evidências para autenticar o código e conceder permissões; b) evidência: são as propriedades do código utilizadas pelo CLR para conceder permissões. Evidências relacionadas a localização incluem: (i) Uniform Resource Locator (URL) de origem; (ii) site de origem; (iii) diretório da aplicação; (iv) zona de origem (computador local, intranet, internet). Evidências relacionadas 2.2 .NET Framework 25 ao autor do código incluem: (i) strong name (uma forma de assinar digitalmente as assemblies usando uma chave privada); (ii) certificado digital X.509 da organização que publicou o código; (iii) valor hash da assembly; c) permissões: representam os direitos do código de acessar recursos protegidos e executar operações privilegiadas. Por exemplo, o código deve ter a permissão FileIOPermission para acessar o sistema de arquivos, e RegistryPermission para acessar o registro do sistema operacional. Uma listagem das permissões prédefinidas do .NET Framework pode ser encontrada no anexo A; d) polı́ticas: as polı́ticas de segurança de acesso do código são configuradas pelos administradores e determinam as permissões concedidas às assemblies. Essas polı́ticas podem ser estabelecidas em quatro nı́veis: corporação, máquina, usuário e a application domain. As polı́ticas de segurança são mantidas em arquivos de configuração em formato Extensible Markup Language (XML); e) grupos de código: cada nı́vel de polı́tica de segurança contém uma coleção hierárquica de grupos de código. Os grupos de código têm uma condição de membro, que especificam quais assemblies fazem parte do grupo, e um conjunto de permissões, que contém as permissões que serão concedidas a todas as assemblies cuja evidências combinem com a condição de membro do grupo. A fig. 2.3 apresenta uma visão simplificada da segurança de acesso do código. Primeiramente a assembly é carregada. O CLR coleta evidências da assembly e as avalia contra a polı́tica de segurança. A saı́da dessa operação é um ou mais conjuntos de permissões que definem as permissões concedidas para a assembly. Durante a execução, o código que acessa recursos ou realiza operações privilegiadas faz uma demanda de permissões. Todas as classes do .NET Framework que acessam recursos protegidos exigem permissões adequadas. Por exemplo, a classe FileStream exige a permissão FileIOPermission, e a classe Registry exige a permissão RegistryPermission (MEIER et al., 2003). As polı́ticas de segurança são avaliadas em cada nı́vel (corporação, máquina, usuário, application domain), e o conjunto de permissões que cada nı́vel concedeu é combinado usando uma operação de intersecção. Uma intersecção garante, por exemplo, que um usuário não possa conceder permissões adicionais que não foram concedidas pelo administrador da corporação. Conforme Watkins e Lange (2002), cada nı́vel das polı́ticas de segurança tem sua própria árvore de grupos de código, que expressam as configurações de cada nı́vel. O conjunto de grupos de código é organizado na forma de uma árvore. Sempre que a condição 2.2 .NET Framework 26 de membro em um nodo da árvore for satisfeito, o conjunto de permissões daquele nodo é concedido à assembly e os nodos filhos são examinados. Caso a condição de membro não seja satisfeita, o conjunto de permissões não é concedido e os nodos filhos não são examinados. Fonte: Meier et al. (2003). Figura 2.3 – Visão simplificada da segurança de acesso do código. A fig. 2.4 ilustra os grupos de código de um nı́vel da polı́tica de segurança. Uma assembly com origem da URL www.monash.edu.au seria avaliada da seguinte maneira: O nodo raı́z tem uma condição de membro “All code”, que é satisfeita por qualquer código. O conjunto de permissões (PSet, na figura) associado ao nodo, “Nothing”nesse caso, é concedido à assembly e a avaliação continua com os nodos filhos. O próximo nodo examinado exige que o código seja carregado do computador local. Como essa condição não é satisfeita, o conjunto de permissões desse nodo não é concedido, e qualquer nodo filho é ignorado. O nodo seguinte tem uma condição de membro que exige que o código seja carregado da Internet. Como essa condição é verdadeira, o código recebe o conjunto de permissões “Internet”e a verificação prossegue com os nodos filhos. O código não teve origem 2.2 .NET Framework 27 da URL www.microsoft.com, então o conjundo de permissões “MSPSet”não é concedido. O conjunto de permissões “MonashPSet”é concedido pelo fato do código ter origem da URL www.monash.edu.au. A condição do nodo filho não é satisfeita, pois o código não tem um strong name de m-Commerce. O último nodo a ser avaliado requer que o código seja originário da intranet. Essa condição não é satisfeira e as permissões não são concedidas. Todos os conjuntos de permissões concedidos dentro do mesmo nı́vel da polı́tica de segurança são combinados usando uma operação de união. Ao final do processo, as permissões da assembly são o resultado de ∪permissões {N othing, Internet, M onashP Set}. Fonte: Watkins e Lange (2002). Figura 2.4 – Grupos de código de um nı́vel da polı́tica de segurança. 2.2.2 ASP.NET O ASP.NET é uma plataforma de programação construı́da sobre o .NET Framework e utilizada para criar aplicações para web. O ASP.NET mantém o mesmo modelo de desenvolvimento do Active Server Pages (ASP) mas contém muitas inovações que permitem fácil separação da funcionalidade principal de uma aplicação e de sua apresentação (MICROSOFT CORPORATION, 2002a; REILLY, 2002). Ao mesmo tempo que o ASP é poderoso e simples de usar, sua arquitetura apresenta alguns problemas, conforme notado por Butler e Caudill (2002): 2.2 .NET Framework 28 a) o código ASP fica complicado muito facilmente, devido à mistura de códigos de servidor e de cliente, e a forma desestruturada de desenvolver um programa; b) o ASP não apresenta um real modelo de componentes, o que exige a necessidade de se escrever código para tudo que se deseja fazer; c) o código do programa fica misturado com o código de apresentação, o que gera problemas quando programadores e designers trabalham juntos. Também é difı́cil suportar vários tipos de clientes e internacionalização de aplicações; d) a combinação ASP e Internet Information Services (IIS) não é sempre a plataforma mais confiável. A tolerância a falhas do ASP é relativamente baixa e um programa mal escrito e ineficiente pode facilmente prejudicar o desempenho de todo o servidor; e) colocar em produção aplicações ASP que utilizam componentes Component Object Model (COM) é difı́cil, visto que os componentes COM precisam ser registrados e são bloqueados pelo sistema operacional quando em uso. Gerenciar aplicações, especialmente aquelas que utilizam vários servidores, tem se mostrado um grade desafio. Mesmo que o ASP.NET apresente um modelo de desenvolvimento similar ao do ASP, não constitui apenas uma nova versão. É uma nova plataforma que contém melhorias nos aspectos de segurança, escalabilidade e estabilidade (MICROSOFT CORPORATION, 2004b). Entre os vários benefı́cios do ASP.NET e de sua nova arquitetura, Butler e Caudill (2002), Reilly (2002), Parihar et al. (2002) destacam: a) integração com o .NET Framework ; b) o uso do CLR em tempo de execução provê uma série de serviços para as aplicações; c) independência de linguagem, inclusive uso de várias linguagens em uma mesma aplicação; d) código compilado, oposto ao ASP que é interpretado.; e) melhor desempenho, devido ao código compilado. Como todas aplicações .NET, o código-fonte é compilado em código intermediário, e a compilação para código nativo ou binário dá-se no momento da execução; f) um modelo de objetos rico para os desenvolvedores, simplificando o desenvolvimento e diminuindo a quantidade de código necessário nas páginas; g) uso extensivo de componentes. Além de vários componentes embutidos na plataforma, é possı́vel criar componentes personalizados, que podem ser substituı́dos 2.2 .NET Framework 29 em tempo de execução; h) possibilidade de utilização de toda a biblioteca de classes do .NET Framework em qualquer aplicação; i) a distribuição de aplicações simplificada, bastando copiar os programas e componentes para o local desejado; não há necessidade de instalação ou registro de componentes; j) as configurações da aplicação ficam todas em um arquivo XML, que pode ser facilmente estendido e modificado. Um dos componentes fundamentais do ASP.NET é o Web Form. Um Web Form é a página web que os usuários visualizam no navegador, e é uma página dinâmica que pode acessar recursos do servidor (arquivos, banco de dados, etc). Para criar essas páginas são utilizados controles do ASP.NET para criar os elementos de interface mais comuns. A possibilidade de se utilizar componentes embutidos na plataforma, ou de criar componentes personalizados simplifica a codificação das páginas (MICROSOFT CORPORATION, 2004b). Segundo Anderson et al. (2001, p. 150), um Web Form não difere muito de uma página web tradicional e também é criado como resultado de uma requisição Hypertext Transport Protocol (HTTP). O servidor cria a página, envia os dados para o cliente, fecha a conexão HTTP e descarta qualquer informação sobre a requisição. Quando um Web Form é requisitado do servidor os componentes que formam aquela página são compilados em uma unidade (ANDERSON et al., 2001, p. 142). Os componentes podem ser: a) o arquivo .aspx sendo requisitado; b) classes contendo código para aquela página; c) qualquer controle do usuário utilizado pela página. No ASP.NET uma página é realmente um objeto executável que produz saı́da Hypertext Markup Language (HTML), e também um objeto derivado da classe pré-definida Page, que, como qualquer outro objeto, tem uma série de estágios de processamento (inicialização, processamento, limpeza). O ASP.NET é baseado em eventos. O modelo de eventos primário dos Web Forms é gerar eventos no cliente e processá-los no servidor. O processo gera uma nova requisição HTTP para a mesma página para que a execução ocorra no servidor. Esse processo é conhecido como viagem de ida e volta ao servidor (Server round-trip). Como o mecanismo de comunicação HTTP é sem informação de estado (Stateless), 2.2 .NET Framework 30 o servidor não guarda nenhuma informação sobre as requisições anteriores do cliente. Isso significa que os valores dos campos de formulários e o estado dos objetos instanciados pela página são perdidos. Para lidar com essa natureza, a arquitetura dos Web Forms utiliza um conceito chamado ViewState. O ViewState contém o estado de todos os controles na página, e é mantido durante os server round-trips. 2.2.3 SERVIÇOS DO WINDOWS Os serviços do Windows (Windows Services) são aplicações que executam como processos em segundo plano e podem ser iniciadas automaticamente quando o sistema operacional inicia. Estas aplicações são ideais para tarefas que não requerem interação com o usuário (MICROSOFT CORPORATION, 2003). Além disso, podem ser criadas utilizando qualquer linguagem .NET, visto que a biblioteca de classe do .NET Framework contêm classes que possibilitam criar, instalar, implementar e gerenciar serviços do Windows. Um serviço do Windows pode ser instalado em qualquer computador rodando Windows Server 2003, Windows XP, Windows 2000 ou Windows NT, e executa continuamente, até que um usuário o pare, ou até que o computador seja desligado. Tarefas comuns realizadas por serviços do Windows são o gerenciamento de conexões de redes e monitoramento do acesso e utilização de recursos. Robinson et al. (2001) explica que três tipos de programas são necessários para operar um serviço: o programa do serviço propriamente dito, um programa para controle do serviço e um programa de configuração do serviço. Além desses programas, o Service Control Manager (SCM) exerce uma função muito importante. O SCM é uma parte do sistema operacional que se comunica diretamente com os serviços e envia requisições para que os serviços sejam iniciados, parados, suspensos e reiniciados. O programa do serviço implementa a funcionalidade do serviço, e contém três partes: uma função main (o ponto de inı́cio do programa), uma função service-main e um handler. A função main deve registrar junto ao SCM o ponto de entrada da função service-main de cada serviço existente no programa, de forma que o SCM possa chamar essa função quando o serviço deve ser iniciado. A função service-main implementa a funcionalidade do serviço e tem a responsabilidade de registrar um handler junto ao SCM. Este handler, por sua vez, é responsável por tratar eventos gerados pelo SCM. Eventos gerados pelo SCM incluem parar, suspender, reiniciar o serviço ou executar alguma ação personalizada. 2.3 Web standards 31 O programa de controle de serviço permite que o estado de um serviço seja controlado. Este programa interage com o SCM para enviar códigos de controle aos serviços, cujo handler deve reagir aos eventos. Também pode-se descobrir o estado atual de cada serviço. Um serviço não pode simplesmente ser copiado para um servidor, pois precisam de configurações especiais no registro do sistema operacional. Esse é o propósito do programa de configuração do serviço. Um serviço pode ser configurado para iniciar de forma automática, manual, ou não iniciar. Também deve ser configurado de forma a ser executado sob o contexto de segurança de uma conta de usuário, e o sistema operacional deve ser informado de quais outros serviços cada serviço depende. Além dessas configurações, um programa de configuração de serviço pode ser usado para mudar os parâmetros de configuração ou para remover o serviço. O .NET Framework provê um namespace chamado System.ServiceProcess, que contém classes necessárias para implementar as três partes de um serviço: a) para implementar um programa de serviço extende-se, por meio de herança, a classe ServiceBase; b) usa-se a classe ServiceController para implementar um programa de controle de serviço; c) as classes ServiceProcessInstaller e ServiceInstaller são usadas para instalar e configurar os serviços. O diagrama de seqüência da fig. 2.5 ilustra a interação entre o SCM, o serviço implementado, a classe ServiceBase e os métodos nativos da Application Programming Interfaces (API) do sistema operacional quando o serviço é iniciado e finalizado. 2.3 WEB STANDARDS Web standards é um conjunto de especificações desenvolvidas pelo World Wide Web Consortium (W3C) para resolver vários dos problemas relacionados ao desenvolvimento para Internet. Zeldman (2003) cita, entre outros: (i) custos elevados de desenvolvimento e atualização de sites; (ii) custos elevados com hospedagem, devido à enorme quantidade de código nas páginas; (iii) incompatibilidade entre diferentes versões do mesmo navegador; (iv) incompatibilidade entre navegadores diferentes. A padronização é uma questão importante em qualquer área. Os navegadores da web finalmente estão suportando padrões, então faz sentido utilizá-los corretamente. 2.3 Web standards 32 Fonte: Robinson et al. (2001, p. 1033). Figura 2.5 – Interação dos componentes durante uma requisição de inı́cio e finalização de um serviço. Conforme Zeldman (2003, p. 53–6), os web standards resolvem estes problemas dividindo qualquer página da web em três componentes: a) estrutura: a estrutura de uma página é representada por uma linguagem de marcação que contém texto formatado de acordo com seu significado estrutural. As linguagens de marcação utilizadas com web standards são Extensible Hypertext Markup Language (XHTML) e XML; b) apresentação: linguagens de apresentação (Cascading Style Sheets (CSS) 1 e 2) formatam a página, controlando a tipografia, posicionamento dos elementos, cores, etc; c) comportamento: Um modelo de objetos padrão (Document Object Model (DOM)) e uma versão padronizada de JavaScript (ECMAScript) permitem que sejam criados comportamentos e efeitos que funcionam em diferentes plataformas e navegadores. 2.4 Trabalhos correlatos 33 Alguns benefı́cios do uso de web standards, segundo Zeldman (2003, p. 42–3) incluem: redução de custos; suporte a múltiplos navegadores e plataformas; suporte a dispositivos não tradicionais, como telefones celulares, computadores de mão, leitores de escrita Braille e leitores de tela; separação do estilo da estrutura e comportamento; uso de marcação baseada em XML; garantia de funcionalidade em navegadores e dispositivos que ainda não foram criados ou mesmo imaginados. 2.4 TRABALHOS CORRELATOS A Universidade de Valladolid (UNIVERSIDAD DE VALLADOLID, [2004?]) e a Universidade do Estado de Ural (URAL STATE UNIVERSITY, [2004?]) apresentam um sistema de juiz on-line para correção de problemas em concursos de programação. Ambos os sistemas rodam em plataforma Linux e aceitam programas escritos em C, C++, Java e Pascal, além de apresentarem um vasto conjunto de problemas que podem ser resolvidos e submetidos para correção. Os usuários podem submeter os programas por e-mail ou pelo site. O BOCA (SILVA, 2003) é sistema desenvolvido em linguagem PHP: Hypertext Preprocessor (PHP) pela PUC-SP e utilizado para controlar uma competição de programação. O software em si não faz correção dos programas, mas serve como uma interface para as equipes enviarem seus programas, receberem as respostas das correções e também se comunicarem com os juı́zes. O Bees (STACK; EIDE; LEPREAU, 2003) é um ambiente de execução seguro e flexı́vel para executar código móvel escrito em Java. Códigos móveis possibilitam que usuários executem programas arbitrários em máquinas remotas, mas normalmente não podem fazer algo muito útil sem um rico ambiente de execução, e nenhum administrador instalaria tal ambiente se não houver um completo controle sobre os recursos consumidos e acessados pelo código remoto. O Bees trabalha com um mecanismo de autenticação e autorização flexı́veis que permite que os usuários definam o processamento e os protocolos usados para comunicar com máquinas remotas, ao mesmo tempo em que permite que os administradores especifiquem as formas de comunicação e os recursos que podem ser utilizados em tais máquinas. 34 3 DESENVOLVIMENTO DO SISTEMA Este capı́tulo detalha inicialmente os requisitos do sistema desenvolvido (seção 3.1), a especificação do sistema (seção 3.2), a implementação, ilustra o sistema em funcionamento (seção 3.3) e apresenta os resultados obtidos (seção 3.4). 3.1 REQUISITOS PRINCIPAIS DO PROBLEMA A SER TRABALHADO A tab. 3.1 apresenta os requisitos funcionais do sistema desenvolvido. Os requisitos não funcionais do sistema são apresentados na tab. 3.2. Tabela 3.1 – Requisitos funcionais do sistema No Requisito RF01 O sistema web deve permitir cadastro e alteração de dados dos usuários; RF02 O sistema web deve manter um banco de dados com os problemas que o sistema pode resolver, organizados por categoria; RF03 Os usuários podem enviar o código-fonte com a solução de qualquer problema apresentado para que seja corrigido; RF04 O sistema web deve mostrar aos usuários relatórios com informações sobre os programas submetidos para correção, com informações sobre o resultado da correção (solução correta, erro de compilação, solução incorreta); RF05 Os usuários podem receber por e-mail o resultado dos problemas submetidos para correção; RF06 O sistema web deve gerar um ranking de usuários de acordo com o número de problemas corretamente resolvidos; RF07 O sistema web deve gerar relatórios estatı́sticos com a quantidade de soluções corretas e incorretas apresentadas para cada problema cadastrado; RF08 O administrador do sistema pode cadastrar, alterar e excluir categorias de problemas disponı́veis para correção automática; RF09 O administrador do sistema pode cadastrar, alterar e excluir os problemas disponı́veis para correção automática; RF10 O administrador pode criar competições, especificando um conjunto de problemas e um perı́odo de tempo para cada competição; RF11 Os usuários e o administrador do sistema podem efetuar logon no sistema informando credenciais (login e senha). 3.1 Requisitos principais do problema a ser trabalhado Tabela 3.2 – Requisitos não funcionais do sistema No Requisito RNF01 Os problemas submetidos para correção devem ter no código-fonte a identificação do usuário, do problema e opcionalmente da competição; RNF02 O sistema de correção deve prover um ambiente seguro, garantindo que os programas enviados pelos usuários não executarão funções indesejadas ou que possam comprometer a segurança ou estabilidade do sistema; RNF03 Os programas dos usuários têm um limite de uso de tempo de processador e memória, especı́ficos para cada problema e definidos pelo administrador; RNF04 O sistema deve compilar os programas submetidos usando o compilador de C# disponı́vel com o .NET Framework SDK; RNF05 O sistema deverá executar em Windows 2000 Server ou Windows Server 2003, com .NET Framework 1.1 ou 2.0; RNF06 O único custo de software aceitável para execução do sistema é a licença do sistema operacional; RNF07 O sistema deverá ser extensı́vel, permitido adição de módulos para compilação de códigos-fonte escritos em outra linguagem; RNF08 O sistema web deverá usar web standards, e ser compatı́vel com qualquer navegador moderno; RNF09 O sistema web deverá ter uma seção de ajuda explicando como a avaliação automática funciona, a quais restrições os programas estarão sujeitos e algumas instruções de como os programas devem ser escritos para poderem ser avaliados por este sistema; RNF10 O sistema de correção não precisa estar executando para o usuário poder enviar um programa; nesse caso a correção será postergada até o serviço ser iniciado; RNF11 Todo o acesso ao banco de dados deve ser feito através de procedimentos armazenados; RNF12 As conexões ao banco de dados devem utilizar segurança integrada do Windows 35 3.2 Especificação 36 3.1.1 DIAGRAMAS DE CASOS DE USO A fig. 3.1 apresenta um modelo do sistema web através de um diagrama de casos de uso. A especificação dos cenários encontra-se no apêndice A. Figura 3.1 – Diagrama de casos de uso do sistema web. A fig. 3.2 apresenta um modelo do sistema de correção através de um diagrama de casos de uso. A especificação dos cenários encontra-se no apêndice B. 3.2 ESPECIFICAÇÃO A especificação do sistema foi feita utilizando-se a notação Unified Modeling Language (UML). Segundo Object Management Group (2004, tradução nossa), “UML é a forma com que o mundo modela não apenas a estrutura, o comportamento e a arquitetura das aplicações, mas também os processos de negócios e estruturas de dados”. Para modelagem da estrutura de dados foi utilizado o Modelo Entidade-Relacionamento (MER). 3.2 Especificação 37 Figura 3.2 – Diagrama de casos de uso do sistema de correção. A ferramenta utilizada para especificação e modelagem de dados foi o Sybase PowerDesigner. O PowerDesigner combina modelagem de aplicações através de UML, técnicas de modelagem de processos de negócio e técnicas tradicionais de modelagem de banco de dados. Mais informações podem ser encontradas em (SYBASE INC., 2004). Figura 3.3 – Componentes do sistema. O sistema está dividido em vários componentes, conforme ilustrado na fig. 3.3. A arquitetura foi inspirada em um padrão de projeto (Design Pattern) conhecido como Model-View-Controler (MVC). Esse padrão adiciona uma camada intermediária que separa a lógica que controla o estado e o comportamento da interface com o usuário da 3.2 Especificação 38 lógica que controla como os dados são adquiridos e processados. O componente Model (seção 3.2.1) e o componente ReportModel (seção 3.2.2) implementam a parte Model desse padrão. A parte View é implementada pelo componente Web (seção 3.2.6) e o Controller é implementado pelos componentes BLL (seção 3.2.5) e JudgeServer (seção 3.2.7). Além desses, os componentes DALFactory (seção 3.2.4) e IDAL (seção 3.2.3) representam uma camada de persistência. As sub-seções seguintes apresentam em maiores detalhes cada componente. 3.2.1 COMPONENTE MODEL O componente Model contém as entidades de negócio da aplicação. As entidades de negócio armazenam dados utilizados para representar entidades de negócio do mundo real, como produtos ou pedidos. Existem várias formas de representar essas entidades em uma aplicação – por exemplo, XML, DataSets ou classes de orientação a objetos personalizadas (CROCKER; OLSEN; JEZIERSKI, 2002). Neste trabalho as entidades de negócio foram implementadas na forma de classes personalizadas. A fig. 3.4 apresenta o diagrama de classes do componente Model. No diagrama estão representadas as classes e seus relacionamentos, juntamente com os atributos de cada classe. Os métodos construtores e as propriedades get e set para os atributos não estão representados. A classe CategoryInfo representa uma categoria de problemas disponı́vel no sistema. Os problemas são representados pela classe ProblemInfo. Dessa classe, os atributos maxUserCPU, maxKernelCPU e maxMemory representam, respectivamente, a quantidade máxima de tempo de processador em modo de usuário, em modo privilegiado e a quantidade máxima de memória que um programa pode consumir. Cada problema agrega um conjunto de entrada e saı́da (representados pela classe IOSetInfo) de exemplo, e pelo menos um conjunto de avaliação. Os dados de um usuário são representados pela classe UserInfo. O atributo userSubmitID, no formato de um Globally Unique Identifier (GUID), é utilizado para identificar o usuário quando um programa é submetido. Um exemplo de GUID pode ser encontrado no quadro 3.8. A classe ContestInfo representa as competições, que agregam vários usuários e vários problemas. Cada programa enviado para correção é representado pela classe SubmissionInfo. Uma submissão está relacionada a um usuário, a um problema e opcionalmente a uma competição. Uma linguagem de programação (classe LanguageInfo) também está associada a uma submissão. O atributo assembly da classe LanguageInfo indica a assembly em que o módulo da linguagem de 3.2 Especificação 39 programação está localizado, e o atributo type representa o nome completo da classe. Figura 3.4 – Diagrama de classes do componente Model. 3.2.2 COMPONENTE REPORTMODEL O componente ReportModel é uma extensão do componente Model e contém classes utilizadas na geração de relatórios e estatı́sticas. A fig. 3.5 ilustra o diagrama de classes do componente ReportModel. Cada classe desse componente agrega uma entidade de negócio e contém algumas informações estatı́sticas. A classe StatsReportInfo agrega uma instância da classe ProblemInfo e contém informações de quantas soluções foram apresentadas para o problema, quantas estão corretas, quantas são inválidas e quantos usuários resolveram o problema. A classe AuthorRankInfo contém informações de quantas soluções um usuário apresentou para correção, quantas estão corretas, quantas são inválidas e quantos problemas esse usuário resolveu. A classe CategoryListInfo agrega 3.2 Especificação 40 uma categoria e guarda informações do número de problemas dessa categoria, e quantos desses problemas foram resolvidos pelo usuário autenticado no momento. De forma similar, a classe ProblemListInfo agrega um problema, e contém dados de quantos usuários resolveram o problema, e se o usuário autenticado conseguiu resolvê-lo. Figura 3.5 – Diagrama de classes do componente ReportModel. Optou-se por separar essas classes do componente Model pelo fato de estas não constituirem realmente entidades de negócio e apresentarem informações redundantes. A razão da criação dessas classes para relatório é o desempenho. Dessa forma utiliza-se os recursos de sumarização de dados do Sistema Gerenciador de Banco de Dados (SGBD) e evita-se a criação de várias instâncias de objetos apenas para sumarizar dados. 3.2.3 COMPONENTE IDAL O componente IDAL contém as interfaces para os componentes de lógica de acesso a dados1 . Componentes DAL recuparam dados e gravam os dados das entidades de negócio na base de dados (CROCKER; OLSEN; JEZIERSKI, 2002). As interfaces2 do componente IDAL definem as operações que cada classe de um 1 Data Access Logic (DAL) Uma interface define um contrato. Uma classe ou estrutura que implementa uma interface deve aderir ao seu contrato (MICROSOFT CORPORATION, 2004b). 2 3.2 Especificação 41 componente DAL deve ter. Dessa forma podem-se implementar diferentes componentes para acesso à diferentes tipos de fontes de dados. Fontes de dados incluem SGBD, serviços de diretório, arquivos texto, arquivos XML, arquivos de dados proprietários, entre outros. Figura 3.6 – Diagrama de classes do componente IDAL. A fig. 3.6 representa o diagrama de classes desse componente. Nessa figura, a interface IUser define as operações de persistência relativas a usuários. A operação ListUsers() retorna uma lista de objetos UserInfo. A operação LogOn() retorna o código de identificação de um usuário se as credenciais fornecidas (login e senha) forem válidas. A operação GetUser() retorna um objeto UserInfo a partir do código de identificação do usuário, enquanto a operação GetUserBySubmitID() retorna um objeto UserInfo a partir do identificador de submissão de um usuário (no formato de um GUID). As operações Insert(), Update() e Delete() recebem como parâmetro um objeto UserInfo e respectivamente, inserem, atualizam ou excluem os dados da fonte de dados. De forma similar, as interfaces IProblem, ICountry, ISubmission, ICategory, IContest, IReports e ILanguage definem as operações de persistência relativas a problemas, paı́ses, submissões, categorias, 3.2 Especificação 42 competições, relatórios e linguagens de programação respectivamente. Neste trabalho implementou-se um componente DAL especı́fico para acesso aos SGBD Microsoft SQL Server 2000 e Microsoft MSDE 2.0. A fig. 3.7 ilustra o modelo conceitual do banco de dados para esse sistema, gerado com base nas classes da fig. 3.4. Figura 3.7 – Modelo conceitual do banco de dados. 3.2.4 COMPONENTE DALFACTORY O componente DALFactory implementa uma variação do padrão de projeto Abstract Factory para criação do componente DAL a ser utilizado na aplicação. 3.2 Especificação 43 Segundo Gamma et al. (1996), o padrão Abstract Factory provê uma interface para criar famı́lias de objetos relacionados ou dependentes sem especificar suas classes concretas. Como a Factory encapsula a responsabilidade e o processo de criar objetos concretos, isola os clientes das classes de implementação. Clientes manipulam instâncias através das interfaces abstratas. Nesse contexto, as interfaces do componente IDAL são os produtos abstratos e as classs do componente DAL para MSDE correspondem ao produtos concretos. O componenente DALFactory implementa as funções da fábrica abstrata e da fábrica concreta. Conforme ilustra diagrama de classes (fig. 3.8), esse componente contém apenas uma classe, com métodos estáticos para instanciar cada uma das classes de acesso a dados definidas pelas interfaces do componente IDAL. Figura 3.8 – Diagrama de classes do componente DALFactory. 3.2.5 COMPONENTE BLL O componente BLL implementa as regras de negócio mais comuns do sistema, usadas pelos componentes Web e JudgeServer. A fig. 3.9 ilustra o diagrama de classes desse componente. Nenhuma parte da aplicação acessa a camada de dados diretamente. Elas o fazem utilizando-se deste componente, o que garante uma manutenção simplificada das regras de negócio. A classe Validator contém regras de validação de dados. A classe User contém operações que implementam as regras associadas a operações com usuários. A operação ValidateCommom() implementa regras para validação de dados que são comuns às operações Insert() e Update(). Outras classes também implementam uma operação ValidateCommom() que têm propósitos semelhantes em suas respectivas classes. A classe 3.2 Especificação 44 Figura 3.9 – Diagrama de classes do componente BLL. Problem implementa ainda uma operação ValidateIOSet() para validação dos conjuntos de entrada e saı́da associados ao problema. A classe Submission implementa operações relativas aos programas submetidos para correção. As operações UpdateStatus(), UpdateIdentifications() e UpdateResouceUsage() são utilizadas para atualizar o status de uma submissão, atualizar as identificações (usuário, problema e competição) e atualizar os recursos consumidos pelo programa (tempo de processador e quantidade de memória), respectivamente. A operação JudgeStatus() retorna o status atual do sistema de correção (parado, executando), e a operação SignalJudge() é utilizada quando o sistema web faz uma submissão para sinalizar ao sistema que correção que um novo programa deve ser corrigido. As classes Contest, Category, Reports, Language e Country implementam as regras para operações relacionadas a competições, categorias, relatórios, linguagens de 3.2 Especificação 45 programação e paı́ses, nessa ordem. Não estão incluı́das nesse componente as regras muito especı́ficas do sistema de correção. Essas regras foram incluı́das na modelagem do sistema de correção, apresentada na seção 3.2.7. 3.2.6 COMPONENTE WEB O componente Web contém a lógica de apresentação do sistema web. A fig. 3.10 apresenta um diagrama com as possibilidades de navegação desse sistema. Figura 3.10 – Diagrama de navegação do sistema web. O diagrama de seqüência da fig. 3.11 ilustra a interação dos componentes durante o envio de uma solução. Quando o usuário solicita a página, o sistema web recupera a lista de linguagens de programação disponı́veis através do método ListLanguages() da classe Language do componente BLL. A página solicita para a classe BLL.Submission o status do 3.2 Especificação 46 Figura 3.11 – Interação dos componentes com o sistema web durante o envio de uma solução. 3.2 Especificação 47 sistema de correção. Em seguida a página é exibida para que o usuário preencha os dados. Quando o usuário preenche os dados, é criada uma instância da classe SubmissionInfo do componente Model, passada para o método Submit() da classe Submission. Esse método invoca no mesmo objeto o método VerifySourcesPath() para verificar se o arquivo de configuração da aplicações indica em que diretório os programas fontes enviados devem ser salvos. É feita uma solicitação à classe Factory do componente DALFactory para a criação de uma instância do objeto Submission do componente de acesso a dados, através do método CreateSubmission(). Esse método verifica no arquivo de configuração qual componente de acesso a dados deve ser utilizado (VerifyAssemblyPath()), chama o método CreateInstance(), que irá carregar a assembly (LoadAssembly()) e instanciar a classe. A classe Submission do componente BLL invoca então o método Submit() do componente de acesso a dados para persistir as informações da submissão. Por fim, é invocado o método SignalJudge() para sinalizar ao sistema de correção a existência de um novo programa a ser corrigido. 3.2.7 COMPONENTE JUDGESERVER O componente JudgeServer implementa a funcionalidade do sistema de correção automatizado. A fig. 3.12 apresenta o diagrama de classes desse componente. A classe Judge contém alguns métodos públicos que serão invocados pelo serviço do Windows. O método Start(), Stop() e JudgeRequest() são invocados, respectivamente, quando o serviço do Windows solicita que o sistema de correção seja iniciado, finalizado e quando há uma nova submissão para ser avaliada. O método MailResults() envia um email com o resultado da correção do programa para o usuário. Os demais métodos são explicados juntamente com o diagrama de seqüência da fig. 3.13. O atributo judgingThread é uma referência para a thread principal do sistema. O atributo event é usado para sincronização entre threads e o atributo exit é uma flag que indica quando o sistema está em processo de finalização. Os atributos p, processOut e processErr representam, respectivamente, uma referência a um novo processo criado para executar o programa do usuário, a saı́da padrão desse processo e a saı́da de erros desse processo. Os atributos listener e portNumber são usados para abrir uma porta TCP no sistema de correção. O atributo requestsPending é um contador de quantos programas estão prontos para ser avaliados. A interface ILanguageModule define um contrato para os módulos de linguagens de programação. Essa interface define métodos que os módulos de linguagem de pro- 3.2 Especificação 48 gramação devem implementar para compilar o programa, verificar a segurança3 , ler as identificações4 do programa e definir como o programa compilado deve ser carregado. A classe DotNetLanguageModule é uma classe abstrata que implementa as operações SafeVerification(), GetIdentifications() e CreateProcessStartInfo(), que são comuns a todos os programas compilados na plataforma .NET. Isso simplifica a implementação de módulos para compilação de outras linguagens .NET, pois é preciso apenas sobrescrever o médoto Compile(). No caso da implementação de uma linguagem independente do .NET Framework deve-se implementar todas as operações da interface. A classe CSharpLanguageModule implementa o módulo para compilação em linguagem C#. Figura 3.12 – Diagrama de classes do componente JudgeServer. A interação dos componentes durante o processo de avaliação de uma submissão é exibida no diagrama de seqüência da fig. 3.13. O método WaitForSubmissions() da classe Judge implementa o loop principal do sistema. Quando o sistema web notifica o sistema de correção da existência de uma nova submissão, o método JudgeSubmission() é 3 4 Apenas a segurança que não pode ser verificada em tempo de execução. Identificação do usuário, do programa e opcionalmente da competição. 3.2 Especificação 49 Figura 3.13 – Interação dos componentes do sistema de correção durante a correção de uma solução. 3.3 Implementação 50 invocado para iniciar o processo de correção. É criada uma instância do módulo de linguagem de programação especı́fico para essa submissão. No diagrama, foi utilizado o módulo para C#.NET. Ao módulo da linguagem é solicitado que compile o programa, recupere as identificações se existirem (identificação do usuário, competição e do problema), verifique se o programa usa alguma classe ou função potencialmente perigosa e que crie um objeto ProcessStartInfo. O objeto ProcessStartInfo contém as informações de como um processo deve ser iniciado. Em seguida, a classe Judge invoca o método StartMonitorProcess(), que vai iniciar um novo processo para execução do programa do usuário e monitorar sua execução. O método WrapperListener() abre uma porta TCP que fica aguardando uma sinalização. O programa do usuário é carregado para execução dentro de um Wrapper (programa que “empacota”outro programa). Esse Wrapper vai criar um novo Application Domain e carregar o programa do usuário para executar dentro dele. Quando o programa do usuário finaliza, a classe Judge recebe uma sinalização através da porta TCP. O sistema de correção vai então ler a saı́da do programa (ReadOutput()), verificar a saı́da de erros (ReadError()), obter a quantidade de recursos utilizados (GetPerfData()), verificar se o programa não excedeu a quantidade máxima de tempo de processador e memória permitidos (MaxCPUExceeded() e MaxMemoryExceeded()), e verificar se a resposta gerada é correta (VerifyAnswer()). 3.3 IMPLEMENTAÇÃO Esta seção apresenta detalhes sobre a implementação do sistema proposto. Suas subseções apresentam as ferramentas utilizadas para o desenvolvimento (seção 3.3.1), o banco de dados (seção 3.3.2), os componentes (seção 3.3.3), o sistema web (seção 3.3.4), o sistema de correção (seção 3.3.5) e dois estudos de caso do sistema em funcionamento (seção 3.3.6). 3.3.1 TÉCNICAS E FERRAMENTAS UTILIZADAS O sistema web foi desenvolvido utilizando tecnologia ASP.NET para código do servidor, e tecnologias compatı́veis com web standards (XHTML, CSS) para código cliente. Para o sistema de correção, foi implementado um serviço do Windows que utiliza o componente JudgeServer (apresentado na seção 3.2.7). Ambos os sistemas foram implementados em plataforma .NET, utilizando-se a linguagem C#.NET. A ferramenta utilizada para codificação foi o VisualStudio .NET. O 3.3 Implementação 51 VisualStudio é uma Integrated Development Environment (IDE) para desenvolvimento de aplicações em .NET. 3.3.2 BANCO DE DADOS O SGBD utilizado foi o Microsoft MSDE 2.0. O MSDE é uma versão de menor porte, porém compatı́vel com o Microsoft SQL Server. Isso assegura que o mesmo componente DAL utilizado para acesso ao MSDE pode ser utilizado para acesso ao SQL Server, sem nenhuma modificação. Optou-se pela utilização do SGBD Microsoft MSDE 2.0 por ser de distribuição gratuita, de forma que tem-se disponı́vel todo o poder de processamento e recursos de um SGBD de grande porte, sem o custo associado as licensas. A forma de acesso ao SGBD foi a utilização de Stored Procedure (SP). Segundo Microsoft Corporation (2004c), uma SP é um grupo de comandos Structured Query Language (SQL) que ficam armazanados no servidor e são compilados e executados como uma unidade. SP são similares a procedimentos em linguagens de programação, de forma que podem ter parâmetros, executar operações e chamar outras SP e retornar valores para a rotina que a chamou. Entre as vantagens de utilização de SP estão: a) permitem programação modular; b) permitem uma execução mais rápida, pois o código é compilado e otimizado apenas na primeira execução; c) reduzem o tráfego da rede, pelo fato de a aplicação enviar menos código SQL para o servidor; d) servem como mecanismo de segurança, pois podem ser concedidas permissões de executar para a SP, mas não permissões de acesso as tabelas base. CREATE PROCEDURE ContestsListByUser @UserID INT AS SET NOCOUNT ON SELECT c.ContestID, c.StartAt, c.EndAt, c.Visibility FROM Contests c INNER JOIN ContestsUsers cu ON c.ContestID = cu.ContestID WHERE cu.UserID = @UserID ORDER BY StartAt DESC Quadro 3.1 – Procedimento armazenado para listar as competições de um usuário. O quadro 3.1 mostra a SP utilizada para listar as competições que um usuário está 3.3 Implementação 52 inscrito. Para auxı́lio ao desenvolvimento do componente de acesso a dados (DAL), utilizouse o Microsoft Data Access Application Block (DAAB). O DAAB é um componente gerenciado5 que expõe classes com métodos para auxiliar na execução de comandos em um servidor de banco de dados Microsoft SQL Server de uma forma robusta e eficiente (MICROSOFT CORPORATION, 2004a). O DAAB encapsula as operações de criar uma conexão ao banco de dados, criar uma transação, criar um comando, criar os parâmetros para as SP e executar o comando em uma única chamada. O quadro 3.2 exemplifica a chamada a SP ContestsListByUser passando o valor “1”para o parâmetro @UserID. SqlDataReader dr = SqlHelper.ExecuteReader(SqlHelper.CONN STRING, "ContestsListByUser", new object[] { user.UserID }) Quadro 3.2 – Código para chamar o procedimento armazenado ContestsListByUser. 3.3.3 COMPONENTES O esqueleto das classes para criação dos componentes foi gerado pelo Sybase PowerDesigner. Além dos atributos e métodos presentes nos diagramas de classes, as classes implementantam também métodos construtores6 e propriedades. Propriedades são um recurso da linguagem C# que implementam as operações get e set para os atributos. O quadro 3.3 representa os atributos e propriedades da classe CountryInfo do componente Model. Cada componente foi compilado em uma assembly separada e instalado no Global Assembly Cache (GAC). O GAC é uma área para instalação de assemblies compartilhadas por várias aplicações (MICROSOFT CORPORATION, 2004b). 3.3.4 SISTEMA WEB O sistema web é um sistema de informação que implementa o gerenciamento de usuários, problemas e competições. Este é dividido em dois grupos de acesso: o administrador pode gerenciar as categorias, os problemas e as competições disponı́veis no sistema. 5 6 Componente .NET. Método chamado automaticamente na inicialização de uma classe. 3.3 Implementação 53 #region Attributes private byte countryID; private string name; #endregion #region Properties public byte CountryID { get { return countryID; } } public string Name { get { return name; } } #endregion Quadro 3.3 – Atributos e propriedades da classe CountryInfo. Os usuários podem manter seu cadastro, inscreverem-se em competições públicas, visualizar os problemas e as estatı́sticas e enviarem suas soluções. A seção 3.3.6 demonstra o sistema em funcionamento nesses dois nı́veis. Para proteger a área restrita ao administrador do sistema foram utilizados os recursos de segurança existentes no .NET. O código do quadro 3.4 foi adicionado ao arquivo de configuração do sistema web 7 . Esse código configura o sistema de segurança para permitir que apenas o usuário identificado pelo nome “1”8 possa acessar o diretório “admin”. <location path="admin"> <system.web> <authorization> <allow users="1"/> <deny users="*"/> </authorization> </system.web> </location> Quadro 3.4 – Configuração de segurança para a área restrita ao administrador do sistema web. Para que o sistema de segurança saiba o nome dos usuários, o valor deve ser informado no momento da autenticação do usuário. O quadro 3.5 exibe o código que autentica o usuário e informa ao sistema de segurança o nome. Optou-se por informar ao sistema de segurança o código do usuário ao invés do 7 8 Web.config. Código do usuário administrador. 3.3 Implementação 54 FormsAuthentication.SetAuthCookie(ui.UserID.ToString(), false); Quadro 3.5 – Código para autenticação do usuário no sistema web. nome. O sistema de segurança disponibiliza uma propriedade User em todas as páginas ASP.NET. Utilizando-se a sentença User.Identity.Name, pode-se recuperar o nome do usuário autenticado. Nessa implementação, tal sentença recupera o código do usuário, que é posteriormente usado para acesso ao banco de dados para recuperar as informações necessárias. 3.3.5 SISTEMA DE CORREÇÃO O sistema de correção automatizado consiste de um serviço do Windows, que instancia e inicia o componente JudgeServer e um Wrapper. O quadro 3.6 ilustra os métodos do serviço do Windows. O método OnlineJudge() é o construtor da classe do serviço, e cria uma nova instância da classe Judge, do componente JudgeServer. Os métodos OnStart(), OnStop() e OnCustomCommand() tratam as requisições de inicialização, finalização e execução de ações personalizadas que são enviadas pelo SCM. private Judge judgeServer; public OnlineJudge() { judgeServer = new Judge(); } protected override void OnStart(string[] args) { judgeServer.Start(); } protected override void OnStop() { judgeServer.Stop(); } protected override void OnCustomCommand(int command) { if (command == 128) //128 é flag p/ sinalizar judge judgeServer.JudgeRequest(); } Quadro 3.6 – Código do serviço do Windows. O método Submission.SignalJudge() do componente BLL (exibido no quadro 3.7 3.3 Implementação 55 e especificado na seção 3.2.5) é executado quando um usuário faz uma submissão pelo sistema web e envia ao serviço de correção uma requisição para executar uma ação personalisada. A ação personalizada definida nesse serviço invoca o método JudgeRequest() da classe Judge, fazendo com que o sistema esteja ciente de uma nova submissão e inicie o processo de execução, caso não esteja corrigindo outra submissão no momento. public class Submission { . . . private void SignalJudge() { ServiceController judgeService = new ServiceController("OnlineJudgeService"); try { judgeService.ExecuteCommand(128); //128 é flag p/ sinalizar judge } catch {} } . . . } Quadro 3.7 – Código do método Submission.SignalJudge() do componente BLL. Ao receber a notificação de que existe uma nova submissão, o sistema de correção acessa o banco de dados para recuperar informações sobre a submissão. É então criada uma instância do módulo de compilação especı́fico para a linguagem de programação que o usuário escolheu no momento da submissão da solução. Esse módulo vai fazer a compilação do codigo-fonte, verificar se o programa tem identificações do usuário, do problema e da competição e verificar se o programa não tenta executar nenhuma ação potencialmente perigosa. Para o módulo de correção de programas em linguagem C#, a forma de identificação utilizada foi através de atributos. Atributos são declarações descritivas que fazem uma anotação nos elementos do programa (MICROSOFT CORPORATION, 2004b). O quadro 3.8 exemplifica um atributo com a identificação do usuário, do problema e da competição. A vantagem da utilização de atributos no lugar de comentários no código-fonte é que a infra estrutura do .NET Framework reconhece e provê fácil acesso às informações definidas em atributos. A verificação de segurança para programas em C# não limita o uso de qualquer 3.3 Implementação 56 [assembly: OnlineJudgeIdentification( UserID="B63C5208-813A-468F-9E6F-7C58ABBB10A7", ProblemID=2, ContestID=5)] Quadro 3.8 – Atributo para identificação do programa submetido para correção. classe ou método, visto que o sistema de segurança verifica em tempo de execução se o programa tem permissões para utilizar as classes. Como o programa do usuário recebe permissões bem restritas, as operações privilegiadas não serão executadas. No entanto, um módulo de compilação para uma linguagem que não suporte segurança em tempo de execução deverá limitar o uso de classes e métodos restritos, potencialmente varrendo o código-fonte. O método StartMonitorProcess() da classe Judge é o responsável por iniciar o processo com o Wrapper para correção e monitorá-lo. O uso do Wrapper se fez necessário a partir de uma limitação encontrada, descrita na seção 3.4.1. O papel do Wrapper é iniciar o programa do usuário dentro do mesmo processo do Wrapper, em um Application Domain separado. A fig. 3.14 representa os processos e os Application Domains existentes quando o Wrapper e o programa do usuário estão carregados. Quando o programa do usuário termina, o Wrapper avisa o sistema que correção, que pode então ler a quantidade de recursos utilizados. Figura 3.14 – Relação entre os processos e os Application Domains do sistema de correção e do Wrapper. Conseguir a sincronia ideal entre o sistema de correção e o Wrapper foi complicado e exigiu muito trabalho de remodelagem. Várias dessas dificuldades estão descritas na seção 3.4.1. Depois que o Wrapper foi iniciado, o sistema de correção inicia uma thread para ler a saı́da padrão do programa, uma para ler a saı́da de erros, abre uma porta TCP para 3.3 Implementação 57 receber a sinalização de que o programa do usuário acabou e finalmente envia as entradas secretas para o programa do usuário resolver o problema. O quadro 3.9 mostra o código mais significativo do programa Wrapper. Primeiro é invocado o método CreateAppDomain() (código no quadro 3.10) para criar e configurar as opções de segurança de um novo Application Domain. Esse Application Domain é configurado de forma que a única permissão para seus programas seja de execução. Nenhum acesso a recursos (sistema de arquivos, registro, bancos de dados) é permitido. O programa do usuário é então colocado para executar dentro desse Application Domain. Ao término da execução do programa, o Application Domain é descarregado e o Wrapper invoca o método ComunicaJudge() para informar ao sistema de correção que o programa do usuário terminou e agora é hora de ler a quantidade de recursos utilizados. class Wrapper { . . . public static void Main(string[] args) { . . . AppDomain executeDomain = CreateAppDomain(); try { executeDomain.ExecuteAssembly(programName); } catch (SecurityException) { Console.Error.Write("securityError"); } catch (Exception ex) { Console.Error.Write(ex.Message); } finally { AppDomain.Unload(executeDomain); } ComunicaJudge(); . . . } . . . } Quadro 3.9 – Rotina principal do programa Wrapper. 3.3 Implementação 58 class Wrapper { . . . private static AppDomain CreateAppDomain() { // cria Application Domain AppDomain executeDomain = AppDomain.CreateDomain("executeDomain"); // cria um nı́vel de polı́tica de segurança PolicyLevel domainPolicy = PolicyLevel.CreateAppDomainLevel(); // cria um conjunto de permiss~ ao vazio // e adiciona permiss~ ao SecurityPermission.Execution PermissionSet permSet = new PermissionSet(PermissionState.None); permSet.AddPermission(new SecurityPermission(SecurityPermissionFlag.Execution)); // atribui esse conjunto de permiss~ ao ao grupo de código raiz domainPolicy.RootCodeGroup.PolicyStatement = new PolicyStatement(permSet, PolicyStatementAttribute.LevelFinal); // define polı́tica segurança desse Application Domain executeDomain.SetAppDomainPolicy(domainPolicy); return executeDomain; } } Quadro 3.10 – Rotina CreateAppDomain() do programa Wrapper. Enquanto o Wrapper está executando o programa do usuário, o sistema de correção fica monitorando os recursos utilizados em intervalos regulares. Se for detectado que o programa do usuário consumiu muitos recursos, ele é finalizado imediatamente, antes do seu término natural. Quando os programas dos usuários terminam dentro do limite aceitável de tempo, o sistema de correção lê a saı́da que eles geraram e compara com a saı́da esperada. Com base nessa comparação é feita a avaliação se o programa é correto ou não. O uso de um Wrapper introduz um overhead ao sistema, e os recursos consumidos pelo Wrapper são deduzidos na hora da avaliação do uso excessivo de recursos. 3.3 Implementação 59 3.3.6 OPERACIONALIDADE DA IMPLEMENTAÇÃO Esta seção apresenta dois estudos de caso do sistema em funcionamento. O primeiro deles apresenta as funcionalidades disponı́veis para o administrador. O segundo apresenta o sistema disponı́vel para os demais usuários. 3.3.6.1 FUNCIONALIDADES PARA ADMINISTRAÇÃO DO SISTEMA As funcionalidades para administração do sistema estão isoladas no diretório “/admin”da aplicação web, e podem ser acessadas apenas pelo usuário administrador. As funcionalidades disponı́veis são gerenciamento de categorias, problemas e competições. A fig. 3.15 exibe a tela para cadastro de categorias. A fig. 3.16 mostra a tela de cadastro de problemas e a fig. 3.17 a tela para indicar a quais categorias um problema pertence. Um problema pode pertencer a várias categorias. Além da entrada e saı́da de exemplo, um problema pode ter um ou mais conjuntos de entrada e saı́da de avaliação. A tela para cadastro de conjuntos de avaliação é exibida na fig. 3.18. No caso de um problema ter mais de um conjunto de avaliação, o programa do usuário é executado mais de uma vez. Figura 3.15 – Tela de cadastro de categorias. A fig. 3.19 mostra a tela para cadastro de competições, e a fig. 3.20 mostra a tela para indicar quais problemas fazem parte dessa competição. Como a competição foi especificada como pública, não é necessário indicar os usuários dessa competição. 3.3.6.2 FUNCIONALIDADES PARA USUÁRIOS DO SISTEMA Esta seção apresenta as funcionalidades disponı́veis para os usuários do sistema. A fig. 3.21 apresenta a tela para cadastro de usuários. Para visualizar os problemas disponı́veis para correção, o usuário entra antes na 3.3 Implementação 60 Figura 3.16 – Tela de cadastro de problemas. Figura 3.17 – Tela para indicação das categorias dos problemas. 3.3 Implementação 61 Figura 3.18 – Tela de cadastro de conjuntos de entrada e saı́da para avaliação. Figura 3.19 – Tela de cadastro de categorias. Figura 3.20 – Tela para indicação dos problemas de uma competição. 3.3 Implementação 62 Figura 3.21 – Tela de cadastro de usuários. lista de categorias (fig. 3.22). Essa lista mostra o nome da categoria, o número de problemas na categoria e o número de problemas que o usuário já resolveu nessa categoria. Figura 3.22 – Tela com a lista de categorias. A fig. 3.23 mostra os problemas disponı́veis em cada categoria, com uma indicação de quantos usuários resolveram cada problema e quais foram resolvidos pelo usuário. A tela com os detalhes do problema é exibida na fig. 3.24. A tela da fig. 3.25 mostra as competições que o usuário está inscrito e as competições em que ele pode se inscrever. O link inscrever só aparece para usuários autenticados. Os detalhes da competição são exibidos na tela da fig. 3.26. Como a competição ainda não 3.3 Implementação 63 Figura 3.23 – Tela com a lista de problemas por categoria. Figura 3.24 – Tela com os detalhes do problema. 3.3 Implementação 64 iniciou, a lista de problemas dessa competição não está visı́vel. Figura 3.25 – Tela com as competições. Figura 3.26 – Tela com os detalhes da competição. A tela fig. 3.27 é usada para submeter programas para correção. O usuário pode escolher se deseja receber um e-mail com o resultado da correção. O sistema só enviará o e-mail se o usuário estiver autenticado no momento da submissão, ou se o sistema encontrar a identificação do usuário no programa submetido. A fig. 3.28 exibe a tela com a lista das últimas submissões que o sistema recebeu. Nessa tela pode-se ver que a última submissão enviada (SubmissionID 67) foi considerada correta. Para ilustrar exemplos de programas maliciosos, foram enviados os programas do quadro 3.11 e do quadro 3.12. O primeiro deles é um loop infinito, que sem recursos de proteção consumiria excessivo tempo de processador. O segundo programa tenta apagar o arquivo do device driver para o processador Pentium III no diretório do sistema operacional. A fig. 3.29 mostra os resultados do sistema de correção para esse dois programas 3.3 Implementação 65 Figura 3.27 – Tela para submissão de programas. Figura 3.28 – Tela com a lista das últimas submissões. 3.4 Resultados e discussão 66 using Kirchner.TCC.OnlineJudgeIdentification; [assembly: OnlineJudgeIdentification(ProblemID=1)] class Teste { public static void Main() { while(true); } } Quadro 3.11 – Programa malicioso que consome muito tempo de CPU. using Kirchner.TCC.OnlineJudgeIdentification; [assembly: OnlineJudgeIdentification(ProblemID=1)] class Teste { public static void Main() { File.Delete(@"C:\WINDOWS\system32\drivers\p3.sys"); } } Quadro 3.12 – Programa malicioso que tenta acessar o disco. maliciosos. O programa com loop infinito é o SubmissionID 73. Esse programa recebeu a avaliação “Limite de tempo excedido”(TL) e foi finalizado, depois de consumir pouco mais tempo de processador do que o permitido para esse problema. O programa que tenta acessar disco (SubmissionID 76) recebeu a avaliação “Função restrita”(RF). Durante a execução, esse programa gerou uma exceção de segurança e foi finalizado. A fig. 3.30 mostra a tela com as estatı́sticas das submissões para cada problema cadastrado, e a tela da fig. 3.31 mostra o ranking dos autores cadastrados no sistema. 3.4 RESULTADOS E DISCUSSÃO O sistema de correção implementado é similar em termos de funcionalidade aos existentes na Universidade de Valladolid (UNIVERSIDAD DE VALLADOLID, [2004?]) e na Universidade do Estado de Ural (URAL STATE UNIVERSITY, [2004?]), com a diferença que executa em sistema operacional Windows e aceita programas em linguagem C#. Esses sistemas apresentam um conjunto de problemas a serem resolvidos, podem criar competições, gerenciam usuários e apresentam estatı́sticas sobre os problemas e usuários 3.4 Resultados e discussão 67 Figura 3.29 – Resultados do sistema de correção para os dois programas maliciosos submetidos a correção. Figura 3.30 – Tela com as estatı́sticas dos problemas. Figura 3.31 – Tela com ranking de autores. 3.4 Resultados e discussão 68 cadastrados. Uma diferença entre esses sistemas é que eles aceitam envio de soluções por e-mail, além do site. O sistema web apresenta funcionalidades similares ao BOCA, utilizado para gerenciar competições. Como não foi projetado unicamente para gerenciar competições, esse sistema web não apresenta, por exemplo, recursos para comunicação com os juı́zes. No entanto, pode gerenciar usuários, problemas e competições. O sistema de correção constitui um ambiente seguro para execução de código arbitrário, recurso existente no Bees. O Bees apresenta mecanismos mais avançados para gerenciamento de uso de recursos do código móvel do que o sistema implementado. No entanto, o sistema de correção apresenta recursos que garantem que um programa não poderá danificar a máquina local, nem consumir excessivos recursos computacionais. Para extensão do sistema e adição de módulos para compilação em outras linguagens de programação, deve-se implementar um componente que extenda a classe DotNetLanguageModule, para linguagens .NET, ou implemente a interface ILanguageModule no caso de uma linguagem que não execute na plataforma .NET. Essa classe e interface estão ilustrados no diagrama de classes da fig. 3.12. O método Compile() deve compilar o código-fonte do usuário e retornar as mensagens de erros do compilador quando existentes. O método SafeVerification() deve garantir que o programa seja seguro para execução, quando a segurança não pode ser verificada em tempo de execução. O método GetIdentifications() deve retornar as identificações do usuário, do programa e da competição, e o método CreateProcessStartInfo() deve retornar um objeto do tipo ProcessStartInfo, com os parâmetros de como o programa deve ser inicializado. Para incorporar o módulo ao sistema, deve-se adicionar um registro à tabela Languages. Os campos Name, Assembly e Type são, respectivamente, o nome da linguagem de programação que aparece para o usuário, o nome da assembly com o módulo para compilação e o nome completo da classe, incluindo namespace, que implementa as operações. 3.4.1 DIFICULDADES ENCONTRADAS A maior parte do trabalho transcorreu sem problemas. Foram encontradas algumas pequenas dificuldades na etapa de especificação, devido à pouca experiência com modelagem UML. A maior fonte de problemas foi realmente a implementação do sistema de correção. A primeira dificuldade foi conseguir ler as informações da quantidade de recursos (proces- 3.4 Resultados e discussão 69 sador e memória) utilizados pelo programa do usuário. Ler as informações é simples, pois a classe Process da biblioteca de classes do .NET Framework contém métodos para obter essas informações. As informações apenas estão disponı́veis enquanto o processo está em execução, no entanto, o sistema de correção precisa saber quanto recurso foi consumido ao fim da execução do programa do usuário. A melhor solução encontrada foi a utilização de um Wrapper. Outra solução analisada seria de iniciar o programa do usuário dentro do mesmo processo que executa o sistema de correção. No entanto, isso tornaria inviável obter as informações de recursos utilizados. A uso de um Wrapper introduziu problemas adicionais. Surge a necessidade de sincronização e comunicação do sistema de correção com o Wrapper. A solução menos custosa em termos de desempenho seria utilizar a saı́da de erros para comunicação. Essa opção consumiu poucos recursos, mas apresentava problemas de funcionamento. Com grande freqüência, ambos os processos (sistema de correção e Wrapper ) ficavam bloqueados. A solução adotada e que funcionou muito bem, porém consome mais recursos, é a comunicação através do protocolo TCP. Antes de iniciar o Wrapper, o sistema de correção abre uma porta TCP e fica aguardando um sinal para prosseguir com suas atividades. Teve-se dificuldade de redirecionamento da entrada e saı́da padrão do programa do usuário. A vantagem de utilizar entrada e saı́da padrão é que o programa submetido à correção não precisa ter nenhum tratamento especial para receber as informações. O programa pode simplesmente ler os dados do teclado e escrever na tela com as rotinas que a linguagem de programação disponibiliza. Ainda assim, essa é a forma com que os sistemas de juiz online pesquisados (seção 2.4) funcionam. A classe Process oferece recursos para redirecionar a entrada e saı́da padrão de um processo. A dificuldade existente é que o processo é na verdade o Wrapper, e o programa do usuário é iniciado dentro desse mesmo processo, em um Application Domain a parte. Várias soluções foram pesquisadas, e desenvolveu-se um mecanismo de sincronização entre o sistema de correção e o Wrapper. O mecanismo funcionava bem apenas quando o sistema executava no depurador. Esse mecanismo foi incrementado fazendo com que um dos programas esperasse de 1 a 2 segundos em determinadas situações, para o outro programa concluir alguma atividade. Dessa forma conseguiu-se uma solução funcional, porém muito pouco eficiente em termos de tempo utilizado. Na solução final conseguiuse eliminar a necessidade de esperas, sendo o único mecanismo de sincronização ainda existente o uso de uma conexão TCP para comunicação. 70 4 CONCLUSÕES Este trabalho alcançou na ı́ntegra seu objetivo inicial, que é o de implementar um sistema de correção automática para provas de concursos de programação, que execute em ambiente Windows e aceite programas escritos em linguagem C#.NET. A arquitetura de segurança do .NET Framework demonstrou-se muito robusta, e seu uso facilitou a implementação de um ambiente seguro. O ambiente de desenvolvimento agilizou o processo de codificação, e o depurador integrado foi de grande valia para sanar os erros do sistema de correção. Além da possibilidade de estabelecer um concurso de programação local ou via internet, a implementação serve como referência de um sistema orientado a objetos, dividido em várias camadas e possibilidade de extensão para uso de outros SGBD e outras linguagens de programação. Outrosim, serve como um estudo de caso de implementação das opções de segurança da plataforma .NET. Algumas limitações existentes: a) requer Windows 2000 Server ou Windows Server 2003; b) requer o .NET Framework SDK; apenas o runtime não é suficiente; c) a correção de programas não é tão eficiente, devido ao overhead da criação de processos e comunicação entre eles; a correção de 50 programas com pouco código demorou cerca de 3 minutos. 4.1 EXTENSÕES Sugere-se como extensão desse trabalho a implementação de módulos para outras linguagens .NET, e também para as linguagens C, C++, Java e Pascal. Essas quatro linguagens estão disponı́veis para uso nos sistemas pesquisados e contemplam muitos usuários. Aprimorar o sistema para aceitar submissões por e-mail é um recurso interessante, e presente em ambos os sistemas de correção pesquisados. Também, a modificação do processo de correção, possibilitando correção simultânea de vários programas e melhorando o tempo de resposta quando muitos programas esperam para serem corrigidos. O 4.1 Extensões 71 estudo de alguma técnica que possa eliminar o uso do Wrapper e do uso de comunicação via TCP pode trazer significativos benefı́cios de desempenho. 72 REFERÊNCIAS BIBLIOGRÁFICAS ANDERSON, Richard et al. Professional ASP.NET. Chicago: Wrox Press, 2001. ASSOCIATION FOR COMPUTING MACHINERY. The ACM-ICPC International Collegiate Programming Contest Web Site sponsored by IBM. 2004. Disponı́vel em: <http://icpc.baylor.edu/icp>. Acesso em: 25 ago. 2004. BUTLER, Jason; CAUDILL, Tony. ASP.NET Database Programming Weekend Crash Course. New York: Hungry Minds, 2002. CROCKER, Angela; OLSEN, Andy; JEZIERSKI, Edward. Designing Data Tier Components and Passing Data Through Tiers. Estados Unidos, 2002. GAMMA, Erich et al. Design Patterns: Elements of reusable object-oriented software. Reading, Massachusetts: Addison-Wesley, 1996. GUPTA, Phalguni. ACM ICPC at IIT Kanpur: 14 - 15 December, 2004. 2004. Disponı́vel em: <http://www.acmsolver.org/?itemid=6>. Acesso em: 31 jul. 2004. MANZOOR, Shahriar. Common Mistakes in Online and Real-time Contests. 2004. Disponı́vel em: <http://www.acmsolver.org/?itemid=>. Acesso em: 31 jul. 2004. MEIER, J.D. et al. Improving Web Application Security: Threats and countermeasures. Estados Unidos, 2003. Disponı́vel em: <http://download.microsoft.com/download/d/8/c/d8c02f31-64af-438c-a9f4-e31acb8e3333/Threats Countermeasures.pd>. Acesso em: 16 out. 2004. MICROSOFT CORPORATION. Developing Microsoft ASP.NET Web Applications Using Visual Studio .NET. Estados Unidos, 2002. Apostila do curso. MICROSOFT CORPORATION. Programming with C#. Estados Unidos, 2002. Apostila do curso. MICROSOFT CORPORATION. Data Access Application Block. Estados Unidos, 2004. Manual de software. MICROSOFT CORPORATION. Microsoft .NET Framework SDK Documentation. Redmond, 2004. Manual de software. MICROSOFT CORPORATION. SQL Server Books Online. Estados Unidos, 2004. Manual de software. MICROSOFT CORPORATION. Mcad/mcsd self-paced training kit: Developing xml web services and server components with microsoft visual basic .net and microsoft c# .net. In: . Redmond: Microsoft Press, 2003. cap. 2. Referências Bibliográficas 73 OBJECT MANAGEMENT GROUP. UML Resource Page. 2004. Disponı́vel em: <http://www.uml.org>. Acesso em: 20 nov. 2004. PARIHAR, Mridula et al. ASP.NET Bible. New York: Hungry Minds, 2002. REILLY, Douglas J. Designing microsoft asp.net applications. In: Microsoft Press, 2002. cap. 1. . Redmond: ROBINSON, Simon et al. Professional C#. Chicago: Wrox Press, 2001. SILVA, Ulisses Furquim Freire da. BOCA - Sistema de Submissão. 2003. Disponı́vel em: <http://maratona.ime.usp.br/manualBOCA.pd>. Acesso em: 02 ago. 2004. SKIENA, Steven S.; REVILLA, Miguel A. Programming Challenges: The programming contest training manual. New York: Springer, 2003. STACK, Tim; EIDE, Eric; LEPREAU, Jay. Bees: A secure, resource-controlled, javabased execution environment. In: IEEE CONFERENCE ON OPEN ARCHITECTURES AND NETWORK PROGRAMMING, 6., 2003, San Francisco. Proceedings... Piscataway: IEEE Press, 2003. p. 97–106. STONY BROOK UNIVERSITY. Secure Mobile Code Execution Environment. 2002. Disponı́vel em: <http://seclab.cs.sunysb.edu/seclab1/research/projects/ca-mcc.ht>. Acesso em: 03 ago. 2004. SYBASE INC. PowerDesigner. 2004. Disponı́vel em: <http://www.sybase.com/products/developmentintegration/powerdesigne>. Acesso em: 20 nov. 2004. UNIVERSIDAD DE VALLADOLID. Online Judge - Problem Set Archive. [2004?]. Disponı́vel em: <http://online-judge.uva.es/problemset>. Acesso em: 01 ago. 2004. URAL STATE UNIVERSITY. Problem Set Archive with Online Judge System. [2004?]. Disponı́vel em: <http://acm.timus.ru/default.asp>. Acesso em: 01 ago. 2004. WATKINS, Demien; LANGE, Sebastian. An Overview of Security in the .NET Framework. 2002. Disponı́vel em: <http://msdn.microsoft.com/library/en-us/dnnetsec/html/netframesecover.as>. Acesso em: 17 out. 2004. ZELDMAN, Jeffrey. Designing with web standards. Indianapolis: New Riders, 2003. 74 APÊNDICE A -- CENÁRIOS DOS CASOS DE USO DO SISTEMA WEB A.1 USE CASE ’AUTENTICAÇÃO USUÁRIO’ Cenário principal a)Usuário digita login e senha; b)Sistema compara credenciais fornecidas com o banco de dados; c)Sistema autentica usuário (efetua login). Cenários alternativos Usuário informou login ou senha inválidos: a)Informa usuário que login ou senha são inválidos. A.2 USE CASE ’CADASTRO DE CATEGORIAS’ Precondições a)Usuário deve estar autenticado como administrador Cenário principal a)Administrador define nome para categoria; b)Sistema web guarda as informações e informa que o cadastro teve sucesso. Cenários alternativos Administrador preencheu campos com dados inválidos: a)Informa administrador sobre quais dados são inválidos e solicita correção. A.3 Use Case ’Cadastro de problemas’ 75 A.3 USE CASE ’CADASTRO DE PROBLEMAS’ Precondições a)Usuário deve estar autenticado como administrador Cenário principal a)Administrador define nome para o problema; b)Administrador escolhe categoria para o problema; c)Administrador informa descrição completa do problema; d)Administrador informa entradas e saı́das de exemplo, que serão exibidas a todos os usuários para ilustrar o formato dos dados que o programa irá receber, e o formato dos dados que o programa deverá gerar; e)Administrador informa entradas e saı́das secretas, que serão utilizadas pelo sistema de correção para verificar se o programa resolve corretamente o problema; f)Administrador informa a quantidade máxima de tempo de processador (em ms) e a quantidade máxima de memória (em bytes) que o programa sendo corrigido pode utilizar; g)Sistema web guarda as informações e informa que o cadastro teve sucesso. Cenários alternativos Administrador preencheu campos com dados inválidos: a)Informa administrador sobre quais dados são inválidos e solicita correção. A.4 USE CASE ’CADASTRO USUÁRIO’ Cenário principal a)Usuário acessa sistema web; b)Usuário informa dados solicitados (nome, e-mail, data nascimento, cidade, estado, paı́s, nı́vel de escolaridade, tempo de experiência com programação, login, senha); c)Sistema guarda informações no banco de dados; d)Sistema autentica usuário (efetua login). Cenários alternativos Usuário preencheu campos com dados inválidos: a)Informa usuário sobre quais dados são inválidos e solicita correção. A.5 Use Case ’Criar competições’ 76 Usuário escolheu um login já existente: a)Informa usuário que login já existe e solicita alteração. A.5 USE CASE ’CRIAR COMPETIÇÕES’ Precondições a)Usuário deve estar autenticado como administrador Cenário principal a)Administrador define data/hora inicial e final para a competição; b)Administrador define se a competição é pública ou privativa; c)Administrador define quais usuários irão participar dessa competição; d)Administrador define quais problemas serão utilizados nessa competição; e)Sistema web guarda as informações e informa que o cadastro teve sucesso. Cenários alternativos Administrador preencheu campos com dados inválidos: a)Informa administrador sobre quais dados são inválidos e solicita correção. Administrador não informou usuários no caso de uma competição privativa: a)Informa administrador que em competições privativas é obrigatório especificar usuários e solicita correção. A.6 USE CASE ’ENVIAR SOLUÇÃO’ Cenário principal a)Sistema web pede para usuário especificar qual o arquivo que contém o códigofonte da solução que o usuário deseja enviar; b)Usuário escolhe se quer receber resultados da correção por e-mail; c)Usuário escolhe linguagem de programação que a solução foi escrita; d)Navegador do usuário faz upload do arquivo para servidor web; e)Sistema web recebe o arquivo e o encaminha ao sistema de correção automática; f)Sistema web avisa usuário que arquivo foi recebido com sucesso e o programa será analisado. Cenários alternativos Erro no envio do arquivo: A.7 Use Case ’Inscrever em competição’ 77 a)Sistema notifica usuário da ocorrência de um erro ao fazer upload do arquivo para o servidor, e mostra os detalhes do erro. A.7 USE CASE ’INSCREVER EM COMPETIÇÃO’ Precondições a)Usuário deve estar autenticado. Cenário principal a)Sistema apresenta p/ usuário as competições públicas que ainda não iniciaram, juntamente com a data/hora de inı́cio e fim; b)Usuario informa qual competição ele deseja se inscrever; c)Sistema registra que usuário está inscrito na competição escolhida e notifica sucesso. A.8 USE CASE ’RELATÓRIO DE ESTATÍSTICAS DOS PROBLEMAS’ Cenário principal a)Usuário solicita relatório de submissões; b)Sistema web busca no banco de dados a lista de problemas existentes, juntamente com o número de soluções apresentadas, o número de soluções corretas, o número de soluções inválidas e o número de usuários que resolveram cada problema; c)Sistema web apresenta dados em formato de um relatório p/ internet. A.9 USE CASE ’VISUALIZAR PROBLEMA’ Cenário principal a)Usuário solicita categorias de problemas; b)Sistema web busca no banco de dados informações sobre as categorias e quantos problemas existem em cada uma delas; c)Se o usuário estiver autenticado, será mostrado também o número de problemas que o usuário já resolver nessa categoria; d)Sistema web apresenta a lista de categorias; e)Usuário escolhe categoria; f)Sistema web busca no banco de dados a lista de problemas da categoria escolhida, e o número de usuários que já conseguiram resolver cada problema; A.10 Use Case ’Visualizar ranking autores’ 78 g)Se o usuário estiver autenticado, será mostrado também quais problemas o usuário já conseguiu resolver; h)Sistema web apresenta a lista de problemas; i)Usuário escolhe problema que deseja visualizar; j)Sistema web busca no banco de dados a descrição e entradas e saı́das de exemplo para o problema escolhido; k)Sistema web apresenta os detalhes do problema. A.10 USE CASE ’VISUALIZAR RANKING AUTORES’ Cenário principal a)Usuário solicita ranking de autores; b)Sistema web busca no banco de dados informações sobre os autores e quantos problemas cada um conseguiu resolver; c)Sistema web apresenta dados em formato de um relatório p/ internet. A.11 USE CASE ’VISUALIZAR RELATÓRIO SUBMISSÕES’ Precondições a)Usuário deve estar autenticado. Cenário principal a)Usuário solicita relatório de submissões; b)Sistema web busca no banco de dados os problemas que já foram submetidos por esse usuário, com detalhes sobre cada submissão (data/hora, identificação do problema, resultado do problema - correto, erro de compilação, resultado incorreto, etc -, tempo de execução, quantidade de memória utilizada); c)Sistema web apresenta dados em formato de um relatório p/ internet. 79 APÊNDICE B -- CENÁRIOS DOS CASOS DE USO DO SISTEMA DE CORREÇÃO B.1 USE CASE ’CORRIGIR PROGRAMA’ Cenário principal a)Sistema de correção recebe código-fonte enviado pelo sistema web; b)Sistema de correção compila o código-fonte do programa, gerando uma .NET Assembly (em formato DLL); c)Sistema de correção carrega programa compilado em ambiente de execução seguro; d)Sistema de correção verifica se o programa carregado tem identificação do usuário e do problema sendo resolvido; e)Sistema de correção verifica se o programa carregado tem informações da competição que o usuário está participando; f)Sistema de correção inicia o programa fornecido pelo usuário, e fornece os dados de entrada secretos como parâmetro; g)Sistema de correção compara a saı́da gerada pelo programa com a saı́da esperada para os dados fornecidos; h)Sistema de correção atualiza o banco de dados com as informações sobre a correção do programa; i)Sistema de correção envia um e-mail para o usuário, informando do resultado da correção do programa. Caso aplicável serão enviadas mensagens adicionais (ex: mensagens de erro do compilador em caso de problemas na compilação do programa). Cenários alternativos Erro de compilação: B.1 Use Case ’Corrigir programa’ 80 a)Retorna etapa 8 do fluxo principal. Programa sem identificação de usuário ou do problema: a)Descarta o programa compilado; b)Atualiza banco de dados informando que o programa foi ignorado; Identificação do usuário ou do problema inválida: a)Descarta o programa compilado; b)Atualiza banco de dados informando que o programa foi ignorado; Usuário enviou um problema para uma competição inexistente, que ele não esteja participando, que não tenha iniciado ainda ou já tenha sido finalizada: a)Descarta o programa compilado; b)Atualiza banco de dados informando que o programa foi ignorado; c)Executa etapa 9 do fluxo principal. Programa excedeu tempo de execução ou quantidade de memória permitidos: a)Retorna a etapa 8 do fluxo principal. 81 ANEXO A -- PERMISSÕES PRÉ-DEFINIDAS DO .NET Permissão Descrição DirectoryServicesPermission Requerida para acessar o Active Directory. DNSPermission Requerida para acessar servidores Domain Name System (DNS). EndpointPermission Define um ponto de conexão autorizado por um objeto SocketPermission. EnvironmentPermission Controla leitura e escrita às variáveis de ambiente. EventLogPermission Requirea para acessar o log de eventos do sistema. FileDialogPermission Permito acesso de leitura a arquivos que o usuário especificou em uma caixa de diálogo de arquivos. FileIOPermission Controla acesso aos arquivos e árvores de diretórios. IsolatedStorageFilePermission Controla o uso do sistema de arquivos virtual da aplicação. IsolatedStoragePermission Requerida para acessar a área de armazenamento privado de uma aplicação. MessageQueuePermission Requerida para acessar as filas de mensagens do Microsoft Message Queuing. OdbcPermission Requerida para usar o provedor de dados ADO.NET ODBC. OleDbPermission Requerida para usar o provedor de dados ADO.NET OLE DB. OraclePermission Requerida para usar o provedor de dados ADO.NET Oracle. PerformanceCounterPermission Requerida para acessar os contadores de desempenho do sistema. PrincipalPermission Usada para restringir o acesso a classes e métodos com base na identidade do usuário. Anexo A -- Permissões pré-definidas do .NET PrintingPermission Requerida para acessar impressoras. ReflectionPermission Controla o acesso ao metadados das assemblies. RegistryPermission Controla o acesso às chaves do registro do sistema. SecurityPermission Esta permissão controla o uso da infra estrutura de segurança. ServiceControllerPermission Pode ser usado para restringir o acesso ao SCM. SocketPermission Pode ser usado para restringir a habilidade de criar ou aceitar conexões em um protocolo. SqlClientPermission Pode ser usado para restringir o acesso a fonte de dados SQL Server. UIPermission Pode ser usada para restringir acesso a área de transferência e para restringir o uso de janelas na aplicação. WebPermission Pode ser usado para controlar o acesso a recursos da internet. 82