Skip to content

Conversation

@go-while
Copy link
Owner

NNTP Proxy/Server Core: Initial Implementation (Server.go)

Overview

This pull request introduces the first version of the NNTP proxy/server core in Server.go. The implementation delivers a robust and extensible NNTP server, complete with user authentication, session management, and support for essential NNTP commands.


✨ Features

🔐 User Authentication

  • Authenticates users against a .passwd file.
  • Passwords are securely stored using bcrypt hashes.
  • Supports account expiration and per-user connection limits.

🧑‍💻 Session Management

  • Each client connection is tracked as a session.
  • Automatic cleanup of sessions on disconnect.
  • Tracks per-session statistics (bytes sent/received).

📡 NNTP Protocol Support

  • Utilizes Go's net/textproto for parsing and responding to NNTP commands.
  • Implements core NNTP commands:
    • AUTHINFO
    • CAPABILITIES
    • STAT
    • ARTICLE
    • BODY
    • HEAD
    • QUIT
  • Includes message ID validation.

🔄 Proxy/Server Operation

  • Supports both plain TCP and TLS/SSL connections.
  • Configurable listening ports.
  • Handles multiple concurrent client connections efficiently.
  • Infinite amount of Providers as backend

👥 User Management

  • Add new users via a helper function (writes to .passwd.new.* files).
  • Random username/password generation for automation and scripting.

📝 Logging & Extensibility

  • Comprehensive logging for authentication, errors, and session events.
  • Modular code organization for future extension (more NNTP commands, advanced user management, etc).

📝 Notes

Here’s an explanation of the new proxy-related flags for the PR, in Markdown:


Proxy-Related Flags

  • -proxytcp
    • Type: int
    • Description: If set, starts the NNTP proxy on the specified TCP port (e.g., -proxytcp=1119). Default is 0 (proxy disabled).
  • -proxytls
    • Type: int
    • Description: If set, starts the NNTP proxy on the specified TLS port (e.g., -proxytls=1563). Default is 0 (TLS proxy disabled).
  • -tlscrt
    • Type: string
    • Description: Path to the TLS certificate file for the proxy. Default is fullchain.pem in the current directory.
  • -tlskey
    • Type: string
    • Description: Path to the TLS private key file for the proxy. Default is privkey.pem in the current directory.
  • -proxyadduser
    • Type: string
    • Description: Adds a user to the proxy. Format: 'username|password|maxconns|expires|(no)post'.
      • Password must be cleartext; hashing is done automatically.
      • Expiration can be specified as a Unix timestamp or as a duration (e.g., 7d for 7 days, 12h for 12 hours, 30m for 30 minutes).
      • Example: -proxyadduser="HelloWorld|NotAsecurePassword|5|42d|nopost" creates a user with 5 connections and 42 days until expiration.
  • -proxypasswdfile
    • Type: string
    • Description: Path to the password file for the proxy. Default is .proxypasswd in the current directory.

  • This is the initial implementation; further NNTP commands and features can be added as needed.
  • This PR establishes the foundation for a Go-based NNTP proxy/server.

Feel free to review, test, and suggest enhancements for future NNTP protocol support!

Copilot AI review requested due to automatic review settings June 10, 2025 22:42

This comment was marked as outdated.

@go-while go-while requested a review from Copilot June 10, 2025 23:11

This comment was marked as outdated.

@go-while go-while requested a review from Copilot October 21, 2025 14:49
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

Copilot reviewed 31 out of 33 changed files in this pull request and generated 4 comments.

Comments suppressed due to low confidence (2)

Workers.go:1

  • [nitpick] The label name "loop" is too generic and could be confused with similar labels elsewhere in the codebase. Consider renaming to "transformLoop" or "yencDecodeLoop" to clarify its purpose.
package main

Server.go:1

  • Variable name contains typo: 'bcrpyt' should be 'bcrypt'.
package main

@@ -1 +1 @@
git clone https://github.com/animetosho/rapidyenc.git || exit 1
# test ! -d rapidyenc && git clone https://github.com/animetosho/rapidyenc.git
Copy link

Copilot AI Oct 21, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The entire clone script is commented out but the file still exists. If this functionality has moved to clone_rapidyenc-org.sh, this file should be removed to avoid confusion.

Suggested change
# test ! -d rapidyenc && git clone https://github.com/animetosho/rapidyenc.git

Copilot uses AI. Check for mistakes.
Comment on lines +117 to +122
for i := 0; i < provider.MaxConns; i++ {
waitWorker.Done() // 3 times per worker
waitWorker.Done()
waitWorker.Done()
waitPool.Done() // 1 time per worker
}
Copy link

Copilot AI Oct 21, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The comment claims waitWorker.Done() is called "3 times per worker", but it's called 3 times total in the loop iteration, not per connection. This decrements the counter incorrectly if MaxConns > 1. Should likely be for j := 0; j < 3; j++ { waitWorker.Done() } inside the outer loop.

Copilot uses AI. Check for mistakes.
Comment on lines +312 to +319
ps.Username = "" // Clear username to avoid dangling pointer
ps.Password = "" // Clear username to avoid dangling pointer
ps.ExpireAt = 0 // Clear expiration time
username := ps.Username // Store username for logging
ps.Username = "" // Clear username to avoid dangling pointer
ps.Password = "" // Clear username to avoid dangling pointer
ps.ExpireAt = 0 // Clear expiration time
log.Printf("Closed session for user '%s'", username)
Copy link

Copilot AI Oct 21, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The username is stored for logging (line 315), but then cleared (line 316) before being used in the log message at line 319. The log will always print an empty string.

Suggested change
ps.Username = "" // Clear username to avoid dangling pointer
ps.Password = "" // Clear username to avoid dangling pointer
ps.ExpireAt = 0 // Clear expiration time
username := ps.Username // Store username for logging
ps.Username = "" // Clear username to avoid dangling pointer
ps.Password = "" // Clear username to avoid dangling pointer
ps.ExpireAt = 0 // Clear expiration time
log.Printf("Closed session for user '%s'", username)
log.Printf("Closed session for user '%s'", ps.Username)
ps.Username = "" // Clear username to avoid dangling pointer
ps.Password = "" // Clear username to avoid dangling pointer
ps.ExpireAt = 0 // Clear expiration time

Copilot uses AI. Check for mistakes.
Comment on lines +335 to +337
//cmdSTAT = "STAT"
//cmdIHAVE = "IHAVE"
//cmdPOST = "POST"
Copy link

Copilot AI Oct 21, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These command constants are commented out but still referenced throughout the codebase (e.g., in NetConn.go). If they're no longer needed as constants, remove them entirely. If they are still used, uncomment them.

Suggested change
//cmdSTAT = "STAT"
//cmdIHAVE = "IHAVE"
//cmdPOST = "POST"
cmdSTAT = "STAT"
cmdIHAVE = "IHAVE"
cmdPOST = "POST"

Copilot uses AI. Check for mistakes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants