Package Structure Map
The project is organized into a clean package hierarchy. Understanding the layout makes navigating the codebase straightforward.
Full Package Tree
Package-by-Package Breakdown
com.dfs.common — Data Transfer Objects
Files that travel over RMI. Every class in this package is Serializable.
| Class | Purpose | Critical Fields |
|---|---|---|
FileOperation | Represents a client file-system request | operationType, filename, fileData, username, timestamp, nonce |
OperationResult | The server's response to a client | success, message, fileData, fileList |
UserCredentials | Username + password (on the wire — hashed server-side) | username, password |
ClockMessage | A write operation with Lamport timestamp for TO-Multicast | messageId, senderId, timestamp, operation |
com.dfs.rmi — Remote Interfaces
Interfaces that define the contract between distributed components.
| Interface | Extends | Purpose |
|---|---|---|
ReplicaNodeInterface | Remote | All node operations — client ops + TO-Multicast protocol + Raft |
AuthServiceInterface | Remote | Registration, login, token validation |
com.dfs.node — Replica Server Implementation
The largest package. Contains the core distributed systems logic.
| Class | Lines | Purpose |
|---|---|---|
ReplicaNode | ~745 | Main server — implements ReplicaNodeInterface, TO-Multicast, Raft, file I/O, security |
NodeMain | ~80 | Entry point — parses args, loads config, creates ReplicaNode |
NodeRegistry | ~60 | Stores RMI addresses of all nodes, loaded from nodes.properties |
LogicalClock | ~30 | Lamport clock — tick(), update(), getTime() |
MessageQueue | ~130 | Priority queue + ACK tracking — the TO-Multicast algorithm core |
com.dfs.auth — Authentication Service
| Class | Purpose |
|---|---|
AuthService | Implements AuthServiceInterface — handles registration, login, token management |
AuthMain | Entry point — creates registry, binds AuthService |
PasswordUtils | PBKDF2 hashing, salt generation, constant-time comparison |
com.dfs.client — Interactive CLI
| Class | Purpose |
|---|---|
DFSClient | RMI connection management, method calls to server |
ClientShell | Interactive menu rendering, user input handling, orchestration |
ClientMain | Entry point — creates DFSClient, starts ClientShell |
com.dfs.util — Security Infrastructure
| Class | Purpose |
|---|---|
TLSConfig | Loads keystores/truststore, creates SSL socket factories |
SerializationValidator | ObjectInputStream subclass with class whitelist (FIX 1) |
NonceStore | Tracks seen nonces + timestamps for replay rejection (BONUS) |
com.vulnerable.* — Vulnerable Mirror
Each vulnerable class mirrors its secure counterpart but with the security mechanisms intentionally removed or disabled. Every vulnerability marker is a // VULNERABILITY: <name> comment.
| Vulnerable Class | Mirrors | What's Broken |
|---|---|---|
VulnerableAuthService | AuthService | No TLS, plaintext passwords |
VulnerableReplicaNode | ReplicaNode | All 5 vulnerabilities exposed |
VulnerableNodeMain | NodeMain | useCodebaseOnly=false, no SSL factories |
VulnerableDFSClient | DFSClient | Plain TCP, no cert presentation |
VulnerableClientShell | ClientShell | No nonce/timestamp generation |
VulnerableClientMain | ClientMain | No TLS setup |
VulnerableAuthMain | AuthMain | No TLS, plaintext passwords |
Dependency Direction
client → rmi → common
node → rmi → common
node → util
auth → rmi → common
util → common
(Nothing depends on client, node, or auth — they're top-level)
(Nothing depends on util except node)
(common depends on nothing within the project — it's the base)
This clean dependency graph means:
commonclasses can be modified without touching anything elseutilis self-contained security infrastructure- No circular dependencies anywhere
Next: → Common Layer Deep-Dive