A simple two-peer terminal chat application written in C.
The project uses TCP sockets for communication and POSIX threads to handle sending and receiving messages concurrently. One peer starts the application in host mode and waits for a connection, while the other starts it in client mode and connects to the host.
- TCP-based communication
- Two-peer terminal chat
- Simultaneous sending and receiving of messages
- POSIX threads for concurrent I/O
- Separate host and client modes
- Session-key derivation with libsodium's crypto_kx
- Authenticated message encryption with crypto_secretstream_xchacha20poly1305
- POSIX-compatible system
- make
- libsodium
- GCC or another compatible C compiler
Clone the repository and build the project:
git clone https://github.com/cldprgm/peerchat.git
cd peerchat
makeThe executable will be created as:
./chat
To remove build artifacts:
make cleanTo perform a clean rebuild:
make reBuild and run the unit tests for the source modules:
make testThe host listens for an incoming TCP connection:
./chat -m hostBy default, port 8082 is used.
A custom port can be specified with -p:
./chat -m host -p 9000The client connects to the host using its IPv4 address:
./chat -m client -ip 127.0.0.1A custom port can also be specified:
./chat -m client -ip 127.0.0.1 -p 9000Replace 127.0.0.1 with the host's actual IPv4 address. 127.0.0.1 is suitable only when both processes run on the same machine.
| Option | Description |
|---|---|
-m host |
Start in host mode |
-m client |
Start in client mode |
-ip ADDRESS |
IPv4 address of the host |
-p PORT |
TCP port, from 1 to 65535 |
Start the host in one terminal:
./chat -m hostThen start the client in another terminal:
./chat -m client -ip 127.0.0.1Once connected, both peers can exchange messages in the terminal. For peers on separate networks, firewall rules and/or router port forwarding may be required.
The application exchanges public keys directly over TCP without verifying that they belong to the intended peer. An active attacker positioned between the host and client could replace the public keys during the exchange. The attacker could then derive one key with the host and a different key with the client, decrypt and read messages, and re-encrypt them into the other session. Solution: Verify public-key fingerprints through a separate trusted channel.
args.c
Parses and validates command-line arguments.
network.c
Handles TCP sockets, connections, sending, and receiving messages.
chat.c
Implements the chat logic, terminal input, and background threads.
crypto.c
Initializes cryptographic streams and encrypts/decrypts messages.
main.c
Initializes the application and selects the host or client mode.
- POSIX sockets
- TCP/IP
- POSIX threads (
pthread) - libsodium
- termios
This project is intentionally simple and currently supports:
- one connection per host
- two peers only
- IPv4 addresses
- terminal-based communication
It does not currently provide multiple simultaneous clients, message history, or a graphical interface. Connections across networks may require firewall configuration or port forwarding. The current key exchange is unauthenticated and is vulnerable to active man-in-the-middle attacks, as described above.
This project is available under the MIT License.