diff --git a/README.md b/README.md index d017869..c300232 100644 --- a/README.md +++ b/README.md @@ -24,8 +24,9 @@ As regras do projeto estão no [`AGENTS.md`](AGENTS.md) e o desenho em [`docs/su | 4 | Console de diagnóstico: ping, tracert, DNS, ARP, conexões e rotas (sai como v0.2.3) | `diagnostico` | [#17](https://github.com/manfredjr/mapnet/pull/17) | Publicada na v0.2.5 | | 5 | Ações de manutenção com elevação sob demanda, na aba Manutenção do console (sai como v0.2.4) | `manutencao` | [#18](https://github.com/manfredjr/mapnet/pull/18) | Publicada na v0.2.5 | | 6 | Painel de detalhe do host, com ping, tracert, navegador, área de trabalho remota e pasta compartilhada (sai como v0.2.5) | `detalhe-host` | [#19](https://github.com/manfredjr/mapnet/pull/19) | Publicada na v0.2.5 | -| 7 | Portas TCP comuns abertas, com lista configurável, desligadas por padrão e com confirmação por rede (sai como v0.3.0) | `portas` | Plano em [#26](https://github.com/manfredjr/mapnet/pull/26), código em [#31](https://github.com/manfredjr/mapnet/pull/31) | Em revisão | -| 8 a 10 | Identificação leve, classificação por tipo de equipamento e relatório também em XML e CSV (até a v1.0.0) | a definir | - | A fazer | +| 7 | Portas TCP comuns abertas, com lista configurável, desligadas por padrão e com confirmação por rede (sai como v0.3.0) | `portas` | Plano em [#26](https://github.com/manfredjr/mapnet/pull/26), código em [#31](https://github.com/manfredjr/mapnet/pull/31) | Publicada na v0.3.0 | +| 8 | Identificação leve dos serviços nas portas abertas: título da página, certificado HTTPS, banner SSH, FTP e SMTP, e UPnP (sai como v0.4.0) | `identificacao` | Plano em [#32](https://github.com/manfredjr/mapnet/pull/32) | Plano em revisão | +| 9 e 10 | Classificação por tipo de equipamento e relatório também em XML e CSV (até a v1.0.0) | a definir | - | A fazer | A versão 0.2 segue o desenho em [`docs/superpowers/specs/2026-09-25-mapnet-0.2-painel-do-tecnico-design.md`](docs/superpowers/specs/2026-09-25-mapnet-0.2-painel-do-tecnico-design.md). diff --git a/docs/superpowers/plans/2026-09-26-mapnet-1.0-plano-geral.md b/docs/superpowers/plans/2026-09-26-mapnet-1.0-plano-geral.md index 473b772..70476d4 100644 --- a/docs/superpowers/plans/2026-09-26-mapnet-1.0-plano-geral.md +++ b/docs/superpowers/plans/2026-09-26-mapnet-1.0-plano-geral.md @@ -81,3 +81,58 @@ Olhar portas é o passo em que o programa deixa de só registrar o que a rede mo 1. Varrer a rede de teste com as portas ligadas e conferir, no roteador, a porta 80 ou 443; numa impressora, a 9100; num Windows com compartilhamento, a 445. 2. Varrer de novo com `--sem-portas` e ver que a coluna fica vazia. 3. Rodar `mapnet --varrer --portas 22,80` e conferir o relatório. + +## Fatia 8: identificação leve dos serviços + +Sai como v0.4.0. A fatia 7 diz que a porta está aberta. A 8 pergunta ao serviço quem ele é, com a menor conversa possível, para o técnico saber que a 80 é o painel de um roteador e a 8000 é um gravador de câmeras. + +### O que entra + +- **Só nas portas que a fatia 7 achou abertas.** A identificação depende de **Verificar portas** e nunca sonda porta ou host novo. +- **HTTP (80, 8000, 8080):** um pedido `GET /` com o cabeçalho `Host` igual ao IP e o `User-Agent` `MapNet-MT/`. Lê o título da página (``), o cabeçalho `Server` e, se houver redirecionamento, só anota o endereço do `Location`, sem seguir. +- **HTTPS (443, 8443):** o início da conversa TLS, para ler o certificado (nome, emissor e validade), aceitando certificado vencido ou autoassinado, que é o normal em equipamento de rede. Depois, o mesmo `GET /` da linha acima, dentro do TLS. +- **SSH (22), FTP (21) e SMTP (25):** o servidor fala primeiro. O programa só lê a primeira linha (o banner) e fecha, sem enviar nada. +- **UPnP (SSDP):** um único pedido `M-SEARCH` para o grupo 239.255.255.250, porta 1900, na rede local. Das respostas, fica o que vem de hosts da sub-rede varrida: o `SERVER` e o endereço da descrição. A descrição (XML) é lida do próprio equipamento, e dela saem o nome amigável, o fabricante e o modelo. +- **Telnet (23) fica de fora:** o primeiro texto de um Telnet costuma ser a tela de login, e a fatia não chega perto de login. + +### Onde aparece + +- **Tabela:** coluna **Serviço**, com o texto mais útil do host (modelo pelo UPnP, título da página, nome do certificado ou banner, nessa ordem), e o resto na dica. +- **Detalhe do host:** bloco **Serviços**, uma linha por porta identificada, como `80 HTTP: título "Painel", servidor lighttpd`. +- **Relatório:** a mesma coluna e o mesmo bloco no detalhe, e uma linha no resumo dizendo que a identificação rodou. +- **Linha de comando:** `--identificar`, que só vale junto com `--portas`. + +### Regras + +- **Nada de senha e nada de formulário.** Só o `GET /`. Não segue redirecionamento, não guarda cookie, não manda credencial, não tenta outro caminho além de `/`. +- **Limites:** 16 identificações ao mesmo tempo, 3 s por serviço, no máximo 64 KB lidos por resposta e 200 caracteres guardados por texto. +- **Texto da rede não é confiável:** sai sem caracteres de controle, cortado no limite, e passa pela codificação HTML no relatório. O XML do UPnP é lido com DTD proibido, que barra entidade externa. +- **Cancelar vale para tudo**, como nas outras etapas. +- **A pergunta de confirmação da fatia 7 passa a dizer também o que a identificação envia**, quando ela estiver ligada. + +### Decisão a confirmar + +Recomendação: a identificação vem junto com **Verificar portas**, numa caixa própria, **Identificar serviços**, marcada por padrão e desligada quando as portas estão desligadas. Alternativa: caixa desmarcada por padrão, como as portas. A análise jurídica de 26/09/2026 já trata a identificação por HTTP e TLS como interação normal, e a confirmação por rede continua valendo. + +### Arquitetura + +- `src/mapnet.nucleo/identificacao/`: `IIdentificador` por protocolo (`IdentificadorHttp`, `IdentificadorTls`, `IdentificadorBanner`), `Ssdp` (pedido e leitura das respostas), `DescricaoUpnp` (leitura do XML) e a etapa `EtapaIdentificacao` no `Varredor`, depois das portas, com andamento na barra de estado. +- `HostEncontrado.Servicos`: lista de `ServicoIdentificado` (porta, protocolo, título, servidor, certificado, banner, modelo) e o texto pronto para a tabela, o detalhe e o relatório. +- Rede simulada nos testes: servidor TCP local com respostas prontas, certificado autoassinado gerado no próprio teste e respostas SSDP em texto. + +### Testes + +1. Título da página: com acento, com entidade HTML, com espaços e quebras, sem `<title>`, com charset no cabeçalho e na página. +2. Cabeçalho `Server` e `Location` anotado sem seguir. +3. Certificado autoassinado e vencido lido sem erro, com nome, emissor e validade. +4. Banner SSH, FTP e SMTP, e servidor que não fala nada no tempo limite. +5. Resposta maior que 64 KB cortada, texto com caractere de controle limpo e texto longo cortado em 200. +6. SSDP: resposta de host fora da sub-rede descartada. Descrição UPnP com DTD recusada. +7. Limites de simultaneidade e cancelamento, como na fatia 7. +8. Tabela, detalhe e relatório, com o texto codificado. + +### Como testar + +1. Varrer a rede de teste com portas e identificação: o roteador mostra o título do painel, a impressora o modelo, o NAS o nome pelo UPnP. +2. Varrer só com portas, sem identificação, e ver a coluna Serviço vazia. +3. `mapnet --varrer --portas --identificar --abrir` e conferir o relatório. \ No newline at end of file