89 lines
3.7 KiB
Markdown
89 lines
3.7 KiB
Markdown
# Proposta Técnica: Mecanismo de Descoberta de Portas e Port-Hunting
|
|
|
|
> **Documento de Arquitetura e Especificação para o SDK Web `@cybercore/signer-sdk`**
|
|
|
|
---
|
|
|
|
## 1. Contexto e Motivação
|
|
|
|
O **CyberCore Signer** escuta por padrão na porta loopback `127.0.0.1:21325`. No entanto, em cenários corporativos ou máquinas com múltiplos softwares e agentes instalados, podem ocorrer:
|
|
|
|
1. **Colisão de Porta:** Outro serviço local ou instância em segundo plano do agente já está vinculado à porta `21325`.
|
|
2. **Execução Multi-Usuário / Terminal Server:** Múltiplas sessões de desktop com agentes independentes para cada usuário logado.
|
|
3. **Restrições de Firewall / Segurança Local:** Políticas corporativas que exigem portas específicas.
|
|
|
|
Para suportar portas alternativas sem exigir configuração manual complexa do usuário final, o CyberCore Signer e o SDK Web adotam a estratégia de **Port-Hunting Sequencial**.
|
|
|
|
---
|
|
|
|
## 2. Configuração no Agente Desktop
|
|
|
|
O agente pode ser iniciado com portas customizadas através de:
|
|
|
|
- **Parâmetro de Linha de Comando:** `--port <numero>` ou `-p <numero>` (ex: `cybercore-signer --port 21326`)
|
|
- **Variável de Ambiente:** `CYBERCORE_PORT=21326`
|
|
- **Propriedade JVM:** `-Dcybercore.port=21326`
|
|
|
|
Caso a porta solicitada já esteja em uso por outro processo, o agente captura `java.net.BindException`, emite mensagem acionável no log/console e, no modo gráfico, mantém a interface de gestão disponível alertando sobre a indisponibilidade temporária do socket HTTP.
|
|
|
|
---
|
|
|
|
## 3. Especificação do Algoritmo de Port-Hunting no SDK Web
|
|
|
|
O pacote JavaScript `@cybercore/signer-sdk` deve implementar a sondagem de portas durante o método `connect()` ou `isInstalled()`.
|
|
|
|
### Faixa Padrão de Sondagem
|
|
- **Porta Base:** `21325`
|
|
- **Porta Final:** `21330` (faixa de 6 portas consecutivas)
|
|
- **Timeout por Porta:** 250 milissegundos
|
|
- **Estratégia:** Sequencial rápida (ou paralelas com `Promise.any`)
|
|
|
|
### Algoritmo
|
|
|
|
```typescript
|
|
export interface SignerOptions {
|
|
basePort?: number;
|
|
maxPort?: number;
|
|
timeoutMs?: number;
|
|
}
|
|
|
|
export async function discoverActivePort(options: SignerOptions = {}): Promise<number> {
|
|
const basePort = options.basePort ?? 21325;
|
|
const maxPort = options.maxPort ?? 21330;
|
|
const timeoutMs = options.timeoutMs ?? 250;
|
|
|
|
for (let port = basePort; port <= maxPort; port++) {
|
|
try {
|
|
const controller = new AbortController();
|
|
const timer = setTimeout(() => controller.abort(), timeoutMs);
|
|
|
|
const resp = await fetch(`http://127.0.0.1:${port}/ccsp/v1/status`, {
|
|
method: 'GET',
|
|
signal: controller.signal,
|
|
headers: { 'Accept': 'application/json' }
|
|
});
|
|
clearTimeout(timer);
|
|
|
|
if (resp.ok) {
|
|
const body = await resp.json();
|
|
if (body.status === 'ready' && body.agent === 'CyberCore Signer') {
|
|
return port; // Agente encontrado e operacional nesta porta!
|
|
}
|
|
}
|
|
} catch {
|
|
// Porta indisponível ou conexão recusada; continua para a próxima
|
|
}
|
|
}
|
|
|
|
throw new Error('CyberCore Signer não encontrado na faixa de portas 21325-21330. O agente está em execução?');
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
## 4. Segurança e Mitigações
|
|
|
|
1. **Host Header Restrito:** Cada requisição deve sempre enviar `Host: 127.0.0.1:{port}` ou `Host: localhost:{port}`. O agente rejeita qualquer Host externo com HTTP 403.
|
|
2. **Private Network Access (PNA):** O agente responde com `Access-Control-Allow-Private-Network: true` para compatibilidade com a especificação PNA do Google Chrome/Chromium.
|
|
3. **CORS Rígido:** A rota `/status` responde `status: ready` apenas para fins de handshake; operações de chave privada continuam exigindo `application_id`, autorização prévia e aprovação visual do usuário.
|