
ssh-chat em c moderno

Software Geral de BBS
O SSH-Chatter começou como uma reimplementação em C do servidor Go ssh-chat. Ele espelha/estende o comportamento original enquanto usa padrões modernos de C e um núcleo pequeno e testável. O servidor escuta por conexões SSH/TELNET e coloca cada usuário autenticado em uma sala de bate-papo compartilhada que expõe a mesma superfície de comandos que a implementação de referência em Go.
Você sabe por que demora tanto para entender C? Porque é um instinto.
/rss list, /rss read <tag>, além de /rss add <url> <tag> e /rss del <tag> (apenas operadores) para que a sala possa navegar por manchetes juntos./delete-msg para limpeza direcionada do histórico do chat./bbs que desbloqueia um sistema imersivo de quadro de avisos retro com tags, comentários, bumping e um compositor de várias linhas.
bumped (atividade recente), hot (em alta por pontuação e comentários), top (maior pontuação líquida de upvotes) ou new (data de criação) usando list [hot|top|new|bumped|all].search <consulta>.▲ 12 💬 5) diretamente nas listagens./bbs dentro do modo BBS./asciiart com limite de 640 linhas, um cooldown de dez minutos por IP, saída de várias linhas e atalhos de teclado para cancelar com Ctrl+A e enviar com Ctrl+S ou o padrão >/__ARTWORK_END>./birthday para registrar aniversários, /grant <ip> para que operadores de LAN possam delegar privilégios por endereço, e /revoke <ip> para que administradores LAN principais possam recuperá-los./ban que aceitam endereços IP brutos juntamente com nomes de usuário./weather <cidade> para previsões globais rápidas.

A base de código é intencionalmente compacta para que novos contribuidores possam navegar rapidamente:

mainO branch work diverge regularmente do desenvolvimento upstream para que funcionalidades maiores possam incubar sem interromper o tráfego de produção. Quando for hora de sincronizar com main, puxe a árvore mais recente e faça o merge localmente antes de abrir um pull request:```bash
git fetch origin main
git checkout work
git merge --no-ff origin/main
Resolva quaisquer conflitos no local (as rotinas auxiliares em `src/host_aggregate.c` já espelham o layout usado no `main`, então as mesclagens são geralmente diretas) e execute `make` para confirmar que a compilação ainda é bem-sucedida antes de enviar o resultado.
## Automation hooks
- `host_snapshot_last_captcha` expõe o prompt e a resposta do captcha gerado mais recentemente, juntamente com um timestamp, para que clientes externos possam passar desafios em nome de automação não supervisionada.
## Security hardening
- `scripts/safe_permission.sh` aperta a propriedade e o modo nos arquivos de dados de tempo de execução (estado do BBS, estado de votação, snapshots de cool down e estado geral de chatter). Execute-o após a implantação para confinar o diretório de dados ao `ssh-chatter` e garantir que cada arquivo esteja definido como `0600`. Substitua os destinos passando caminhos explícitos ou exportando `STATE_ROOT` ou as variáveis de ambiente `CHATTER_*_FILE` correspondentes antes da execução.
- Um watchdog do BBS em segundo plano alimenta periodicamente posts e comentários pelo pipeline de moderação de IA (Gemini principal com fallback do Ollama). Posts sinalizados são removidos automaticamente e um aviso é transmitido para a sala.
- Mensagens de chat, arte ASCII e posts/comentários do BBS passam por um pipeline de moderação de IA. Ative-o com `CHATTER_SECURITY_AI=on` (defina `GEMINI_API_KEY` para Gemini; o daemon automaticamente recai para o endpoint local do Ollama em `http://127.0.0.1:11434`). Desative tudo com `CHATTER_SECURITY_FILTER=off`. Se todos os provedores falharem, o filtro se desativa automaticamente para manter as conversas fluindo em vez de descartar conteúdo silenciosamente.
- O transporte SSH está fixado em trocas de chave, cifras e MACs modernos, e cada payload da ponte é envolvido em uma cebola tripla AES-256-GCM, de modo que os relays vejam apenas texto cifrado.
- Submissões suspeitas que acionam o filtro em camadas agora são rastreadas por IP; acertos repetidos disparam um kick e ban automáticos quando ativados, enquanto o detector de reconexão rápida permite janelas de recuperação mais longas para que sessões de rede instáveis possam se reconectar sem serem penalizadas. As entradas de ban automáticas estão **desabilitadas por padrão**; defina `CHATTER_AUTO_BAN=on` (ou `true`/`1`) para ativá-las, ou deixe a variável não definida para manter avisos e limitação de taxa sem escrever entradas de ban automáticas.
- Operadores podem marcar pontos de entrada confiáveis (saídas VPN, proxies reversos, localhost) com `CHATTER_PROTECTED_IPS` (separados por vírgula, padrão `127.0.0.1,::1,192.168.0.1`) para que bans de emergência nunca bloqueiem o daemon fora de seu próprio plano de controle.
## File storage and transfers
- Todos os arquivos gerenciados pelo usuário agora ficam em `/etc/ssh-chatter/user-files` (substitua com `CHATTER_FILESTORE_PATH`, fallback legado: `CHATTER_FILE_STORAGE_ROOT`). O daemon cria o diretório se necessário e mantém os uploads confinados a ele.
- Clientes SSH usam `scp` padrão sem nenhum wrapper personalizado. Trate `/name.ext` como a raiz da árvore de armazenamento: `scp my.zip user@host:/demos/my.zip` escreve em `/etc/ssh-chatter/user-files/demos/my.zip` enquanto `scp user@host:/readme.txt ./` baixa `/etc/ssh-chatter/user-files/readme.txt`.
- Clientes TELNET usam os novos comandos `/filestore`. `/filestore` lista os arquivos disponíveis, `/filestore-upload` inicia uma sessão `rz`, e `/filestore-download <name>` inicia uma sessão `sz`. Instale `lrzsz` (ou qualquer pacote que forneça `rz`/`sz`) no servidor para que o backend ZMODEM possa iniciar esses helpers.
- `/filestore-upload` aceita um destino opcional (por exemplo `/filestore-upload /kitten/meow.png`). SSH-Chatter cria o diretório `/kitten` automaticamente e coloca o arquivo enviado lá, espelhando como o SCP usa caminhos como `user@host:/kitten/meow.png`.
- Ambos os transportes podem ser misturados: SSH para transferências scriptadas não supervisionadas, TELNET para clientes BBS nostálgicos com ferramentas ZMODEM integradas.
## Morse Relay
O SSH-Chatter suporta relay de rádio amador (ham radio).
Isso mostra sinais morse globais.
`/morse on` para ver, `/morse-reply` para enviar.
### Detalhes do Protocolo
A implementação segue a especificação do protocolo Binkp:
- Estrutura padrão de frame Binkp com cabeçalhos de 2 bytes
- Autenticação por senha de sessão (CMD\_PWD/CMD\_OK)
- Mecanismo de keepalive (CMD\_NUL) a cada 60 segundos
- Comando CHAT personalizado (CMD\_CHAT, extensão) para sincronização de mensagens
## Pré-requisitos
Construir o projeto requer um ambiente POSIX com:
- Um compilador compatível com C23 (por exemplo, `gcc` ou `clang`)
- `make`
- Cabeçalhos e biblioteca de desenvolvimento `libssh` (`libssh-dev` no Debian/Ubuntu)
- Cabeçalhos e biblioteca de desenvolvimento `libcurl` (`libcurl4-openssl-dev` no Debian/Ubuntu)
- Cabeçalhos e biblioteca de desenvolvimento `uchardet` (`libuchardet-dev` no Debian/Ubuntu)
- Cabeçalhos e biblioteca de desenvolvimento `icu` (Componentes Internacionais para Unicode) (`libicu-dev` no Debian/Ubuntu)
- Biblioteca de compressão `lz4` e cabeçalhos de desenvolvimento (`liblz4-dev` no Debian/Ubuntu)
- Threads POSIX (geralmente fornecidas pelo `libpthread` do sistema)
- `python3-pygments` (fornece o realçador `pygmentize` para a tela de camuflagem do Tetris)
No Debian/Ubuntu as dependências podem ser instaladas com:```bash
sudo apt-get update
sudo apt-get install build-essential libssh-dev libcurl4-openssl-dev libuchardet-dev libicu-dev liblz4-dev
Clone o repositório e use o Makefile fornecido:```bash
make
Isso produz um binário `ssh-chatter` na raiz do repositório e um objeto compartilhado `libssh_chatter_backend.so` que expõe os
auxiliares de tradução para reutilização em outras aplicações. Limpe os artefatos intermediários com `make clean`.
### Usando o back-end de tradução compartilhado
O objeto compartilhado reutiliza o pipeline de tradução C do servidor (incluindo a preservação de placeholders ANSI) para que outros processos possam
obter traduções sem iniciar o host SSH completo. Vincule com `libssh_chatter_backend.so` e inclua
`include/ssh_chatter/ssh_chatter_backend.h`:```c
#include "ssh_chatter/ssh_chatter_backend.h"
int main(void) {
char translated[4096];
char detected[64];
if (ssh_chatter_backend_translate_line("Hello, world!", "ko", translated, sizeof(translated), detected, sizeof(detected))) {
printf("Detected %s -> %s\n", detected, translated);
}
}
Defina GEMINI_API_KEY (e, opcionalmente, GEMINI_API_BASE ou GEMINI_MODEL) no ambiente para que o auxiliar possa alcançar a API Google Generative Language, espelhando os requisitos de tempo de execução do daemon principal. Pode executar ./scripts/test_gemini_connection.sh antes de iniciar o servidor de chat para verificar se as credenciais permitem chamadas externas; o script imprime a resposta bruta do Gemini para que possa ver se o pedido foi bem-sucedido.
O servidor padrão ouve em 0.0.0.0:2222. Pode ajustar os parâmetros de tempo de execução com os sinalizadores disponíveis:```
Usage: ./ssh-chatter [-a address] [-p port] [-m motd_file] [-k host_key_dir] [-T telnet_port|off] [-J json_port|off]
./ssh-chatter [-h]
./ssh-chatter [-V]
Quando fornecido, `-m` lê a mensagem do dia do caminho do arquivo especificado.
Exemplos comuns:```bash
# Start the chat server on port 2022, loading host keys from /etc/ssh
./ssh-chatter -p 2022 -k /etc/ssh
# Enable telnet access on 0.0.0.0:4242 alongside SSH
./ssh-chatter -T 0.0.0.0:4242
# Serve a custom MOTD from a file and bind to localhost
./ssh-chatter -a 127.0.0.1 -m /etc/ssh-chatter/motd
O diretório de chaves de host deve conter um arquivo ssh_host_rsa_key (e opcionalmente .pub). Gere uma com ssh-keygen -t rsa -b 4096 -f /path/to/dir/ssh_host_rsa_key se não quiser reutilizar as chaves de host SSH do seu sistema. Chaves de host adicionais chamadas ssh_host_ed25519_key e ssh_host_ecdsa_key são carregadas automaticamente quando presentes, para que o servidor possa oferecer algoritmos modernos durante a troca de chaves.
Uma vez em execução, conecte-se com qualquer cliente SSH:```bash ssh -p 2222 user@server-address
O servidor público está disponível em `bbs.chatter.pw` na porta SSH padrão:```bash
ssh -p 2222 [email protected]
Nomes de usuário fornecidos no prompt SSH são usados como seu apelido no chat.
Clientes Telnet podem se conectar com o mesmo conjunto de funcionalidades. A escuta Telnet está habilitada por padrão na porta 2323 e pode ser ajustada ou desabilitada com a flag -T. Forneça -T endereço:porta para sobrescrever o endereço de vinculação (ele herda a vinculação SSH quando omitido; use um host vazio como -T :4242 para escutar em todas as interfaces). Por exemplo, para se conectar via telnet de um terminal retrô:```bash
telnet server-address 2323
Passe `-T off` (ou `-T disable`) para desligar completamente o listener telnet.
### JSON line API
O servidor também expõe um protocolo de linha JSON sobre TCP para automação e integrações externas. Ele escuta na porta `34567` por padrão e pode ser desabilitado ou reconfigurado com `-J`:```bash
# Disable the JSON API
./ssh-chatter -J off
# Bind JSON API on a custom port
./ssh-chatter -J 0.0.0.0:45678
Cada requisição é um único objeto JSON terminado por \n. Respostas e eventos de chat são objetos JSON, também delimitados por nova linha. A API suporta chat geral e os fluxos /poll, /vote, /image, /video, /audio, /files e /asciiart.
Payloads de eventos (servidor → cliente)```json {"type":"event","event":"message","payload":{"id":123,"username":"alice","message":"hello","created_at":1710000000,"system":false,"preserve_whitespace":false,"attachment":{"type":"none","target":"","caption":""}}}
**Exemplos de requisição (cliente → servidor)**```json
{"type":"chat","id":1,"username":"alice","message":"안녕하세요"}
{"type":"image","id":2,"username":"alice","url":"https://example.com/cat.png","caption":"cat"}
{"type":"asciiart","id":3,"username":"alice","message":" /\\_/\\\\n( o.o )\\\\n > ^ <"}
{"type":"poll","id":4,"username":"op","is_operator":true,"question":"Favorite color?","options":["red","blue","green"]}
{"type":"poll","id":5,"username":"bob","action":"vote","choice":2}
{"type":"vote","id":6,"username":"op","label":"weekend","question":"Plan?","options":["hike","rest"],"allow_multiple":true}
{"type":"vote","id":7,"username":"bob","label":"weekend","action":"vote","choice":1}
As respostas ecoam o id e incluem objetos status, message e, opcionalmente, result:```json
{"type":"response","id":4,"status":"ok","message":"poll started","result":{"poll":{"active":true,"allow_multiple":false,"id":10,"question":"Favorite color?","options":[{"index":1,"text":"red","votes":0},{"index":2,"text":"blue","votes":0}]}}}
Para um exemplo executável, veja `scripts/json_api_example.py`:```bash
python3 scripts/json_api_example.py --url tcp://127.0.0.1:34567 --save /tmp/json_api_output.txt
Um script auxiliar é fornecido para automatizar a instalação em sistemas que usam systemd:```bash
sudo ./scripts/install_chatter_service.sh
O que o script faz:
1. Compila o projeto (`make`).
2. Instala o binário resultante em `/usr/local/bin/ssh-chatter`.
3. Cria um usuário e grupo de sistema dedicados `ssh-chatter` (se ainda não existirem).
4. Cria `/var/lib/ssh-chatter` para o estado em tempo de execução (incluindo a chave de host SSH) e `/etc/ssh-chatter` para arquivos de configuração.
5. Gera uma chave de host RSA padrão em `/var/lib/ssh-chatter/ssh_host_rsa_key` quando ausente.
6. Cria um MOTD padrão em `/etc/ssh-chatter/motd` e um arquivo de substituição `/etc/ssh-chatter/chatter.env` para ajustes baseados em ambiente.
7. Escreve `/etc/systemd/system/chatter.service`, recarrega o `systemd`, habilita o serviço e o inicia imediatamente.
A unidade `chatter.service` resultante inicia o servidor com padrões sensatos e concede a capacidade `CAP_NET_BIND_SERVICE` para que a conta de serviço não root possa vincular portas privilegiadas, se necessário.
### Personalizando o serviço
Você pode ajustar os padrões editando `/etc/ssh-chatter/chatter.env` e reiniciando o serviço:```bash
sudo systemctl edit chatter.service # or edit the environment file directly
sudo systemctl restart chatter.service
Variáveis de ambiente suportadas incluem:
CHATTER_BIND_ADDRESS – Endereço IP para vincular (padrão 0.0.0.0).CHATTER_PORT – Porta TCP exposta aos clientes (padrão 2222).CHATTER_MOTD_FILE – Caminho para o arquivo de mensagem do dia (padrão /etc/ssh-chatter/motd).CHATTER_HOST_KEY_DIR – Diretório contendo ssh_host_rsa_key (padrão /var/lib/ssh-chatter).CHATTER_EXTRA_ARGS – Argumentos adicionais anexados à invocação do ssh-chatter.CHATTER_VOTE_FILE – Caminho para o arquivo de estado de votação (padrão vote_state.dat).Trechos de Código de Camuflagem:
Para o recurso de camuflagem Tetris, o runtime espera arquivos de trechos de código em /var/lib/ssh-chatter/.
Este repositório agora inclui exemplos prontos para uso em ./camouflage/ (c.txt, cpp.txt, java.txt, go.txt, js.txt, ts.txt, rust.txt).
Copie-os para o diretório runtime uma vez durante a configuração:```bash
sudo install -d /var/lib/ssh-chatter
sudo cp camouflage/*.txt /var/lib/ssh-chatter/
Pode editar qualquer ficheiro copiado para personalizar o que aparece quando o ecrã de camuflagem está ativo.
O suporte de tradução agora depende da API Google Gemini. Defina o seguinte em `chatter.env` (ou no ambiente) para ativá-lo:
- `GEMINI_API_KEY` – Chave de API secreta usada para autenticar pedidos de tradução.
- `GEMINI_API_BASE` – Substituição opcional para o URL base da API (padrão `https://generativelanguage.googleapis.com/v1beta`).
- `GEMINI_MODEL` – Substituição opcional para o nome do modelo Gemini (padrão `gemini-2.5-flash`).
Quando a tradução está ativa, o chat entrega cada mensagem imediatamente no seu idioma original e segue com uma legenda indentada que contém o texto traduzido assim que a resposta Gemini chega. Os resumos de reações usam o mesmo estilo de legenda, para que as atualizações apareçam diretamente abaixo da mensagem que referenciam.
Se as inserções de legendas inline parecerem bruscas, pode reservar um pequeno buffer de linhas em branco antecipadamente com `/chat-spacing <0-5>`. A definição afeta apenas os tópicos de chat ao vivo—o conteúdo do quadro de avisos continua a traduzir sem reserva—para que possa ajustar o espaçamento para a sua própria sessão sem impactar as publicações longas.
A sua opção de tradução e escolhas de idioma são guardadas em `chatter_state.dat`, para que sessões futuras restaurem automaticamente a mesma configuração quando voltar a conectar-se.
Se preferir instalar sem iniciar imediatamente o serviço, execute o script com `SKIP_START=1`.
Comandos de gestão do serviço:```bash
sudo systemctl status chatter.service
sudo systemctl restart chatter.service
sudo systemctl disable --now chatter.service
-m ou arquivo de configuração gerenciado pelo serviço./help para clientes conectados./ban, /poke)./weather/vote e alternativas de escolha única /vote-single, incluindo /elect <rótulo> <escolha> como um atalho de votação amigável em texto./bbs com marcação, comentários, bumps e um compositor interativo que termina com um terminador sensível ao locale (padrão >/__BBS_END>).Issues e pull requests são bem-vindos. Por favor, inclua passos para reprodução de bugs e certifique-se de que make seja executado com sucesso antes de enviar alterações.
| Caminho | Descrição |
|---|
src/main.c | Análise de linha de comando e inicialização do processo (endereço de bind, porta, MOTD, diretório de chave do host). |
src/host_aggregate.c, include/ssh_chatter/host.h | Implementação do host do chat – ciclo de vida da sessão, manipulação do MOTD e ganchos para lógica futura de broadcast de mensagens. |
src/host | Subsistemas modulares do host que compilam em uma única unidade de tradução através de src/host_aggregate.c. |
include/ssh_chatter | Cabeçalhos compartilhados para o daemon, ferramentas de estresse e o backend de tradução. |
include/ssh_chatter/contexts | Definições para session_ctx_t e estruturas relacionadas que encapsulam o estado por conexão. |
data/banner/banner | Exemplo de banner de boas-vindas que pode ser apontado com CHATTER_WELCOME_BANNER. |
scripts/install_chatter_service.sh | Instalador conveniente que compila o binário, instala-o em /usr/local/bin e configura uma unit systemd (chatter.service). |
scripts/install_dependencies.sh | Instalador mínimo de pacotes para pré-requisitos de compilação em sistemas Debian/Ubuntu. |
CHATTER_GEMINI_COOLDOWN_FILE – Caminho para o arquivo de estado de cooldown do Gemini (padrão gemini_cooldown.dat).CHATTER_SECURITY_FILTER – Defina como off/false/0 para desabilitar o filtro de segurança em camadas (habilitado por padrão).CHATTER_SECURITY_AI – Defina como on/true/1 para habilitar a moderação por IA (desabilitado por padrão).CHATTER_FILESTORE_PATH – Substitui o caminho de armazenamento de arquivos gerenciado (padrão /etc/ssh-chatter/user-files).CHATTER_FILE_STORAGE_ROOT – Fallback legado para o caminho de armazenamento de arquivos gerenciado.CHATTER_MAX_ALLOC_BYTES – Limite superior para uma única tentativa de alocação contígua no gerenciador de memória interno. Por padrão não há limite (SIZE_MAX). Defina isso apenas se quiser impor um limite rígido em uma alocação. Defina como 0, unlimited, inf ou infinity para remover explicitamente qualquer limite./asciiart com rascunhos de 640 linhas, um cooldown de postagem de dez minutos por IP, entrega multilinha e atalhos Ctrl+A/Ctrl+S./game com tetris integrado (transcodificado da implementação C original da era soviética) e liargame, ambos suspensíveis via /suspend! ou Ctrl+Z.