Servidor web em C para estudo
“Publiquei em me blog o código fonte de um servidor WEB que utilizamos para fazer um trabalho acadêmico. Quero compartilhar com todos para que possa auxiliar em seus estudos também.
“Nesse primeiro ano na faculdade tivemos um trabalho em grupo que consistia em criar um servidor WEB utilizando a linguagem C. Este servidor deveria ser capaz de responder a uma requisição GET e mostrar as páginas e arquivos solicitados e também retornar erros de acordo com o que não fosse encontrado.””
Enviado por Jean Carlos O. Guandalini (jeanΘjeanguandalini·com) – referência (jeanguandalini.com).
Impressão minha ou esse código ta bugado (stack overflow) ?
Tem várias funções utilizando sprintf sem checagem de tamanho do buffer origem.
Algum hacker ae poderia esclarecer?
Assim, para um trabalho de primeiro de faculdade ser um servidor WEB escrito em C, e que funcione(não testei), realmente, eu não estou interessado se possui bugs de overflow, pq, MEODEOS, é uma coisa respeitável fazer um trabalho desses.
E como ele mesmo disse, é um trabalho acadêmico, para estudos. Acho que um “hacker” poderia gastar o seu tempo com coisas mais interessantes que achar bugs assim.
Só posso lhe parabenizar Jean!
Parabéns! Vou dar uma olhada no código. Eu já penei para usar sockets para fazer um chat em C, imagino o quanto você deve ter ralado!
Impressiona é o tamanho do código: muito pequeno! – nunca imaginei que um servidor web pudesse ter esse tamanho.
parabéns!
Parabéns pela iniciativa. Também foi bom por colocá-lo em uma página que não possui blog no endereço, pois essas são bloqueadas nas faculdades e universidades públicas (o que acontece, por exemplo, aqui no Paraná).
[]‘s
geek seu traseiro está com buffer overrun.
Eu baixei o código. Os guris estão de parabens pelo trabalho e por compartilhar conosco.
abraços.
boa!
É Geek você tentou desmerecer o trabalho do cara mas não deu não…Parabéns Jean pelo trabalho!!!!
Obrigado pelos comentários pessoal, nesse curso que faço, temos somente uma noção básica da programação C, e nesse trabalho tivemos muito o que pesquisar. Uma preocupação que tive foi comentar muito o código para que qualquer pessoa possa entender o que cada linha faz. Mas realmente serve somente para estudos, para uso em produção precisaria de uma revisao do código por alguém mais experiente na área de C.
Já pensou em publicar este código sob a GPL, pois assim vc garante que ele será livre para ser estudado, garante a autoria e garante que ninguem ou nenhuma empresa registre esse codigo e te processe!
Olha lá, quem sabe um dia isso num fica melhor que Apache!
@geek: Achou problema no código? Corrige e publica aqui para ajudar o Jean a melhorar o trabalho dele. ;)
@Geek,
Consegue escrever algo melhor? Publique! Cada uma!!! :s
Jean Parabens pela iniciativa!
flw
Pessoal, vocês não entenderam, eu não estava criticando o trabalho do Jean que é louvavel e sim tentando alerta-lo sobre possíveis problemas lógicos na implementação do código.
Consegui travar o servidor, vejam abaixo:
Inicializando servidor CesuRedes WebServer v1.0…[OK]
Falha de segmentação
root@filipe-laptop:/home/filipe# telnet localhost 85
Trying 127.0.0.1…
telnet: Unable to connect to remote host: Connection refused
Para reproduzir esse resultado, experimentem mandar uma requisição qualquer sem usar GET :D
Ou seja, consegui realizar o ataque de negação de serviço.
Muito possivelmente conseguiria-mos um root na máquina que estivesse rodando esse servidor, bastanto codar um exploit que
realize algo mais interessante que um DOS, como executar o /bin/bash por exemplo ;)
Não me entendam mal, sou um geek, eu não conseguiria ver um código bugado e não falar nada :)
Caro amigo geek, muito obrigado por explicar um dos bugs, por milagre consegui arrumar, pois não sou tão bom assim em programação. No site agora tem a versão com a correção.
pq brasileiro entende sinceridade ou critica como ataque ? Será a famosa sindrome do vira-lata ?
parabens jean e geek…
Muito legal o projeto…. E novamente mais um post cheio de “faz melhor então” rs…
Imagina se o pessoal do Ubuntu, SUSE, Mandriva, etc.. Abandonassem suas bugzillas dizendo: Se tem bug vc que arrume rs…
E não é porque é um projeto acadêmico que ele tem que ser tratado como exceção não é? Pelo menos onde eu estudo simplesmente usar o while para fazer um serviço de um for já é o suficiente para perder 10% da questão rs…
—–
To dando uma olhada no projeto, muito bacada porém você está esquecendo tornar algumas coisas dependentes das verificações de erro… Por exemplo:
if((sWebServer = socket(AF_INET, SOCK_STREAM, 0)) < 0)
Se retornar erro ainda assim ele executa:
if(listen(sWebServer, CONPEND) < 0)
Hora, se ele não conseguiu criar o socket, obviamente vai dar erro no listen… Logo essa verificação deveria ficar condicionada a anterior…
E por ser tratar de um webserver, quanto menos operações desnecessárias fizer melhor! E no caso, esse tipo de erro pode causar um travamento repentino na server caso o socket retorne erro. Afinal com erro ou não ele ainda entra no loop infinto: while(1).
Fica ai mais uma dica!
Parabéns ao Jean pelo trabalho e ao Geek pelo alerta!
Wallacy, obrigado pela dica, nessa verificação do if que você comentou, tem uma função logo abaixo dela assim:
saidaErro(“Nao foi possivel criar o socket. ”);
Nessa função ele tem um exit, daí não chega a entrar no outro if do listen.
Sobre o while, me falaram mesmo que o mais certo seria utilizar o for, nesse caso você poderia me indicar qual a melhor maneira para esse tipo de loop?
Obrigado
Como são as coisas… Hoje tive que fazer um trabalho de envio e recebimento de arquivos usando socket. Acabei encontrando um código muito parecido com o seu no livro Sistemas Distribuidos – Desenvolvendo Aplicações de Alta Performance no Linux. pag. 283 para ser mais exato. Mesmo assim, valeu por compartilhar seu codigo.
Eu acho que isso poderia ir para um sourceforge e virar um projeto interessante heim :) coloquem! coloquem!
Jean,
Nem tinha visto o exit… Foi só uma olhada superficial mesmo.
Sobre o while… Bem, considerando então a função “saidaErro”, o que você pode fazer por precação é estimar um limite de de “tempo” de espera, caso exista algum problema, mesmo causado por “problemas” externos ao seu programa, você sabe vai ter a segurança de que ele ira se alto finalizar. Estipule um “timeout”… ou algo assim…