uFTP/test/test8.py

139 lines
6.0 KiB
Python

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Created on Sat Jul 19 18:15:07 2025
@author: ugo
"""
import socket
import ssl
import ftplib
from io import BytesIO
def log_command(direction, command, response=None):
"""Log FTP commands and responses"""
if direction == "C":
print(f"C: {command}")
elif direction == "S":
print(f"S: {response}")
elif direction == "ERROR":
print(f"ERROR: {command}")
elif direction == "INFO":
print(f"INFO: {command}")
def verify_rest_violations():
"""
Verify REST-related sequence and implementation violations.
"""
HOST = '127.0.0.1'
PORT = 21
USER = 'username'
PASS = 'password'
FILE = "test_rest.txt"
CONTENT = b"1234567890"
print("\n--- Verifying Rules: REST Command Sequence and Implementation ---")
print("Test Objective: Verify that the REST command correctly limits subsequent commands and handles offsets")
try:
with ftplib.FTP() as ftp:
# Enable debug mode to show all FTP interactions
ftp.set_debuglevel(0) # We handle display ourselves
log_command("INFO", f"Connecting to {HOST}:{PORT}")
ftp.connect(HOST, PORT, timeout=5)
log_command("C", f"USER {USER}")
ftp.login(USER, PASS)
log_command("INFO", "Login successful")
log_command("C", "TYPE I")
resp = ftp.sendcmd("TYPE I")
log_command("S", resp)
# Upload test file
log_command("C", f"STOR {FILE}")
ftp.storbinary(f"STOR {FILE}", BytesIO(CONTENT))
log_command("INFO", f"File uploaded successfully, content: {CONTENT} (length: {len(CONTENT)})")
print("\n" + "="*60)
# Scenario 1: Verify if RETR correctly handles the offset set by REST
print("[+] Scenario 1: Verify if RETR correctly handles the offset set by REST")
print(" RFC Requirement: RETR should start transferring from the byte position specified by REST")
# Reset REST point
rest_offset = 5
log_command("C", f"REST {rest_offset}")
try:
response_rest2 = ftp.sendcmd(f"REST {rest_offset}")
log_command("S", response_rest2)
if not response_rest2.startswith('350'):
print(f" REST {rest_offset} failed: {response_rest2}")
print(f" Expected: 350 Restarting at {rest_offset}")
return
else:
print(f" REST set offset to byte {rest_offset}")
except ftplib.error_perm as e:
log_command("ERROR", f"REST {rest_offset} failed: {e}")
return
# Download file
log_command("C", f"RETR {FILE}")
out = BytesIO()
ftp.retrbinary(f"RETR {FILE}", out.write)
retrieved_content = out.getvalue()
# Detailed analysis of results
print(f"\n Transfer Result Analysis:")
print(f" Original File Content: {CONTENT} (length: {len(CONTENT)})")
print(f" REST Offset: {rest_offset} (starting from byte {rest_offset})")
print(f" Expected Transferred Content: {CONTENT[rest_offset:]} (length: {len(CONTENT[rest_offset:])})")
print(f" Actual Transferred Content: {retrieved_content} (length: {len(retrieved_content)})")
if len(retrieved_content) == len(CONTENT):
print("\n VIOLATION CONFIRMED: RETR implementation ignored the offset set by REST")
print(" Actual Result: Downloaded the entire file, ignoring the REST offset")
print(f" Expected Result: Should only download {CONTENT[rest_offset:]} ({len(CONTENT[rest_offset:])} bytes)")
print(" Violation Explanation: Violates RFC 959 regarding the REST command")
elif len(retrieved_content) == len(CONTENT) - rest_offset:
if retrieved_content == CONTENT[rest_offset:]:
print(" No violation detected. RETR correctly handled the REST offset.")
else:
print(" VIOLATION CONFIRMED: Content mismatch, REST offset handled incorrectly")
print(f" Actual Content: {retrieved_content}")
print(f" Expected Content: {CONTENT[rest_offset:]}")
print(" Violation Explanation: Incorrect REST offset calculation")
elif len(retrieved_content) > len(CONTENT):
print(" VIOLATION CONFIRMED: Retrieved data length exceeds original file size")
print(f" Actual Length: {len(retrieved_content)} bytes")
print(f" Expected Maximum Length: {len(CONTENT)} bytes")
print(f" Expected Length after REST: {len(CONTENT[rest_offset:])} bytes")
print(" Violation Explanation: Severe data transfer anomaly")
else:
print(f" VIOLATION CONFIRMED: Unexpected retrieved content length")
print(f" Actual Length: {len(retrieved_content)} bytes")
print(f" Expected Length: {len(CONTENT[rest_offset:])} bytes")
print(" Violation Explanation: Problem with REST command implementation")
# Clean up test file
try:
log_command("C", f"DELE {FILE}")
#ftp.delete(FILE)
log_command("INFO", "Test file cleanup completed")
except:
log_command("ERROR", "Failed to cleanup test file")
except Exception as e:
print(f"\nError occurred: {e}")
import traceback
print("Detailed error information:")
traceback.print_exc()
print("\nPossible causes:")
print(" - Server connection issues")
print(" - Insufficient permissions")
print(" - Server does not support certain commands")
if __name__ == "__main__":
verify_rest_violations()