 543ab216f9
			
		
	
	543ab216f9
	
	
	
		
			
			🎭 CHORUS now contains full BZZZ functionality adapted for containers Core systems ported: - P2P networking (libp2p with DHT and PubSub) - Task coordination (COOEE protocol) - HMMM collaborative reasoning - SHHH encryption and security - SLURP admin election system - UCXL content addressing - UCXI server integration - Hypercore logging system - Health monitoring and graceful shutdown - License validation with KACHING Container adaptations: - Environment variable configuration (no YAML files) - Container-optimized logging to stdout/stderr - Auto-generated agent IDs for container deployments - Docker-first architecture All proven BZZZ P2P protocols, AI integration, and collaboration features are now available in containerized form. Next: Build and test container deployment. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
		
			
				
	
	
		
			221 lines
		
	
	
		
			6.6 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			221 lines
		
	
	
		
			6.6 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
| package security
 | |
| 
 | |
| import (
 | |
| 	"strings"
 | |
| 	"testing"
 | |
| )
 | |
| 
 | |
| func TestSecurityValidator(t *testing.T) {
 | |
| 	validator := NewSecurityValidator()
 | |
| 	
 | |
| 	// Test IP validation
 | |
| 	t.Run("IP Validation", func(t *testing.T) {
 | |
| 		validIPs := []string{"192.168.1.1", "127.0.0.1", "::1", "2001:db8::1"}
 | |
| 		for _, ip := range validIPs {
 | |
| 			if err := validator.ValidateIP(ip); err != nil {
 | |
| 				t.Errorf("Valid IP %s rejected: %v", ip, err)
 | |
| 			}
 | |
| 		}
 | |
| 		
 | |
| 		invalidIPs := []string{
 | |
| 			"", // empty
 | |
| 			"999.999.999.999", // invalid range
 | |
| 			"192.168.1.1; rm -rf /", // command injection
 | |
| 			"192.168.1.1`whoami`", // command substitution
 | |
| 			"192.168.1.1$(id)", // command substitution
 | |
| 			"192.168.1.1\ncat /etc/passwd", // newline injection
 | |
| 		}
 | |
| 		for _, ip := range invalidIPs {
 | |
| 			if err := validator.ValidateIP(ip); err == nil {
 | |
| 				t.Errorf("Invalid IP %s was accepted", ip)
 | |
| 			}
 | |
| 		}
 | |
| 	})
 | |
| 	
 | |
| 	// Test username validation
 | |
| 	t.Run("Username Validation", func(t *testing.T) {
 | |
| 		validUsernames := []string{"ubuntu", "user123", "_system", "test-user"}
 | |
| 		for _, username := range validUsernames {
 | |
| 			if err := validator.ValidateUsername(username); err != nil {
 | |
| 				t.Errorf("Valid username %s rejected: %v", username, err)
 | |
| 			}
 | |
| 		}
 | |
| 		
 | |
| 		invalidUsernames := []string{
 | |
| 			"", // empty
 | |
| 			"user; rm -rf /", // command injection
 | |
| 			"user`id`", // command substitution  
 | |
| 			"user$(whoami)", // command substitution
 | |
| 			"user\ncat /etc/passwd", // newline injection
 | |
| 			"user name", // space
 | |
| 			"user'test", // single quote
 | |
| 			"user\"test", // double quote
 | |
| 			"123user", // starts with number
 | |
| 		}
 | |
| 		for _, username := range invalidUsernames {
 | |
| 			if err := validator.ValidateUsername(username); err == nil {
 | |
| 				t.Errorf("Invalid username %s was accepted", username)
 | |
| 			}
 | |
| 		}
 | |
| 	})
 | |
| 	
 | |
| 	// Test password validation
 | |
| 	t.Run("Password Validation", func(t *testing.T) {
 | |
| 		validPasswords := []string{
 | |
| 			"", // empty is allowed
 | |
| 			"simplepassword",
 | |
| 			"complex@password#123",
 | |
| 			"unicode-пароль",
 | |
| 		}
 | |
| 		for _, password := range validPasswords {
 | |
| 			if err := validator.ValidatePassword(password); err != nil {
 | |
| 				t.Errorf("Valid password rejected: %v", err)
 | |
| 			}
 | |
| 		}
 | |
| 		
 | |
| 		invalidPasswords := []string{
 | |
| 			"password`whoami`", // command substitution
 | |
| 			"password$(id)", // command substitution  
 | |
| 			"password\necho malicious", // newline injection
 | |
| 			"password'break", // single quote injection
 | |
| 			"password$USER", // variable expansion
 | |
| 		}
 | |
| 		for _, password := range invalidPasswords {
 | |
| 			if err := validator.ValidatePassword(password); err == nil {
 | |
| 				t.Errorf("Invalid password was accepted")
 | |
| 			}
 | |
| 		}
 | |
| 	})
 | |
| 	
 | |
| 	// Test SSH key validation
 | |
| 	t.Run("SSH Key Validation", func(t *testing.T) {
 | |
| 		validKeys := []string{
 | |
| 			"", // empty is allowed
 | |
| 			"-----BEGIN RSA PRIVATE KEY-----\nMIIEpAIBAAKCAQEA...\n-----END RSA PRIVATE KEY-----",
 | |
| 			"-----BEGIN OPENSSH PRIVATE KEY-----\nb3BlbnNzaC1rZXktdjE...\n-----END OPENSSH PRIVATE KEY-----",
 | |
| 		}
 | |
| 		for _, key := range validKeys {
 | |
| 			if err := validator.ValidateSSHKey(key); err != nil {
 | |
| 				t.Errorf("Valid SSH key rejected: %v", err)
 | |
| 			}
 | |
| 		}
 | |
| 		
 | |
| 		invalidKeys := []string{
 | |
| 			"ssh-rsa AAAAB3NzaC1yc2E...", // public key where private expected
 | |
| 			"invalid-key-format",
 | |
| 			"-----BEGIN RSA PRIVATE KEY-----\ntruncated", // malformed
 | |
| 		}
 | |
| 		for _, key := range invalidKeys {
 | |
| 			if err := validator.ValidateSSHKey(key); err == nil {
 | |
| 				t.Errorf("Invalid SSH key was accepted")
 | |
| 			}
 | |
| 		}
 | |
| 	})
 | |
| 	
 | |
| 	// Test command sanitization
 | |
| 	t.Run("Command Sanitization", func(t *testing.T) {
 | |
| 		testCases := []struct {
 | |
| 			input    string
 | |
| 			expected string
 | |
| 			safe     bool
 | |
| 		}{
 | |
| 			{"ls -la", "ls -la", true},
 | |
| 			{"systemctl status nginx", "systemctl status nginx", true},
 | |
| 			{"echo `whoami`", "echo whoami", false}, // backticks removed
 | |
| 			{"rm -rf /; echo done", "rm -rf / echo done", false}, // semicolon removed
 | |
| 			{"ls | grep test", "ls  grep test", false}, // pipe removed
 | |
| 			{"echo $USER", "echo USER", false}, // dollar removed
 | |
| 		}
 | |
| 		
 | |
| 		for _, tc := range testCases {
 | |
| 			result := validator.SanitizeForCommand(tc.input)
 | |
| 			if result != tc.expected {
 | |
| 				t.Errorf("Command sanitization failed: input=%s, expected=%s, got=%s", 
 | |
| 					tc.input, tc.expected, result)
 | |
| 			}
 | |
| 			
 | |
| 			isSafe := (result == tc.input)
 | |
| 			if isSafe != tc.safe {
 | |
| 				t.Errorf("Safety expectation failed for input=%s: expected safe=%v, got safe=%v",
 | |
| 					tc.input, tc.safe, isSafe)
 | |
| 			}
 | |
| 		}
 | |
| 	})
 | |
| 	
 | |
| 	// Test port validation
 | |
| 	t.Run("Port Validation", func(t *testing.T) {
 | |
| 		validPorts := []int{22, 80, 443, 8080, 3000}
 | |
| 		for _, port := range validPorts {
 | |
| 			if err := validator.ValidatePort(port); err != nil {
 | |
| 				t.Errorf("Valid port %d rejected: %v", port, err)
 | |
| 			}
 | |
| 		}
 | |
| 		
 | |
| 		invalidPorts := []int{0, -1, 65536, 99999}
 | |
| 		for _, port := range invalidPorts {
 | |
| 			if err := validator.ValidatePort(port); err == nil {
 | |
| 				t.Errorf("Invalid port %d was accepted", port)
 | |
| 			}
 | |
| 		}
 | |
| 	})
 | |
| 	
 | |
| 	// Test cluster secret validation
 | |
| 	t.Run("Cluster Secret Validation", func(t *testing.T) {
 | |
| 		validSecrets := []string{
 | |
| 			"abcdef1234567890abcdef1234567890", // 32 char hex
 | |
| 			"a1b2c3d4e5f6789012345678901234567890abcd", // longer hex
 | |
| 			"alphanumericSecr3t123456789012345678", // alphanumeric, 38 chars
 | |
| 		}
 | |
| 		for _, secret := range validSecrets {
 | |
| 			if err := validator.ValidateClusterSecret(secret); err != nil {
 | |
| 				t.Errorf("Valid secret rejected: %v", err)
 | |
| 			}
 | |
| 		}
 | |
| 		
 | |
| 		invalidSecrets := []string{
 | |
| 			"", // empty
 | |
| 			"short", // too short
 | |
| 			strings.Repeat("a", 200), // too long
 | |
| 		}
 | |
| 		for _, secret := range invalidSecrets {
 | |
| 			if err := validator.ValidateClusterSecret(secret); err == nil {
 | |
| 				t.Errorf("Invalid secret was accepted")
 | |
| 			}
 | |
| 		}
 | |
| 	})
 | |
| }
 | |
| 
 | |
| func TestValidateSSHConnectionRequest(t *testing.T) {
 | |
| 	validator := NewSecurityValidator()
 | |
| 	
 | |
| 	// Test valid request
 | |
| 	err := validator.ValidateSSHConnectionRequest("192.168.1.1", "ubuntu", "password123", "", 22)
 | |
| 	if err != nil {
 | |
| 		t.Errorf("Valid SSH connection request rejected: %v", err)
 | |
| 	}
 | |
| 	
 | |
| 	// Test with SSH key instead of password
 | |
| 	err = validator.ValidateSSHConnectionRequest("192.168.1.1", "ubuntu", "", 
 | |
| 		"-----BEGIN RSA PRIVATE KEY-----\ntest\n-----END RSA PRIVATE KEY-----", 22)
 | |
| 	if err != nil {
 | |
| 		t.Errorf("Valid SSH key request rejected: %v", err)
 | |
| 	}
 | |
| 	
 | |
| 	// Test missing both password and key
 | |
| 	err = validator.ValidateSSHConnectionRequest("192.168.1.1", "ubuntu", "", "", 22)
 | |
| 	if err == nil {
 | |
| 		t.Error("Request with no auth method was accepted")
 | |
| 	}
 | |
| 	
 | |
| 	// Test command injection in IP
 | |
| 	err = validator.ValidateSSHConnectionRequest("192.168.1.1; rm -rf /", "ubuntu", "password", "", 22)
 | |
| 	if err == nil {
 | |
| 		t.Error("Command injection in IP was accepted")
 | |
| 	}
 | |
| 	
 | |
| 	// Test command injection in username  
 | |
| 	err = validator.ValidateSSHConnectionRequest("192.168.1.1", "ubuntu`whoami`", "password", "", 22)
 | |
| 	if err == nil {
 | |
| 		t.Error("Command injection in username was accepted")
 | |
| 	}
 | |
| } |