sultree
(noun) : a wary oak
what is this?
A SELinux-aware variant of the tree command that filters directory trees based on SELinux security contexts.
Features
- Full tree compatibility: Supports all standard
treecommand options - SELinux filtering: Filter files and directories by SELinux security contexts using the
-Sflag - Pattern matching: Support for wildcard patterns in SELinux context matching
- Security focused: Designed with security best practices and safe defaults
- Memory efficient: Uses iterative traversal for large directory trees
- Safe error handling: Gracefully handles permission denied and broken symlinks
Requirements
- Python 3.8+
- Linux system with SELinux enabled (optional for basic tree functionality)
getfattrutility (part ofattrpackage)
Installation
Quick Start (No Installation)
You can run sultree directly from the source directory:
cd sultree
./sultree /path/to/directory
Development Installation (Editable)
cd sultree
pip install -e .[dev]
This installs sultree in editable mode, so changes to the source code are immediately available.
Regular Installation
cd sultree
pip install .
Usage
Basic Tree Functionality
# Basic directory tree (like standard tree)
sultree /etc
# Show hidden files
sultree -a /home/user
# Directories only, depth limited
sultree -d -L 2 /usr
# Show full paths
sultree -f -L 1 /var/log
# Follow symbolic links
sultree -l /usr/local
SELinux Filtering
# Show only files with specific SELinux type
sultree -S passwd_file_t /etc
# Wildcard patterns in any part of context
sultree -S "*admin*" /var/log
sultree -S "httpd_*" /var/www
sultree -S "*_exec_t" /usr/bin
# Multiple SELinux patterns (OR logic)
sultree -S passwd_file_t -S shadow_t /etc
# Full context pattern matching
sultree -S "system_u:object_r:*:s0" /etc
# Combine SELinux filtering with tree options
sultree -d -S httpd_exec_t -L 1 /usr/sbin
sultree -a -S "*_config_t" /etc
Pattern Matching
# Include only certain file patterns
sultree -P "*.conf" /etc
# Exclude backup files
sultree -I "*.bak" -I "*~" /home/user
# Case-insensitive matching
sultree --ignore-case -P "*.TXT" /tmp
# Apply patterns to directories too
sultree --match-dirs -P "*ssl*" /etc
Advanced Options
# Limit files per directory (performance)
sultree --filelimit 100 /usr
# Stay on one filesystem
sultree -x /
# Suppress file/directory count
sultree --no-report /etc
SELinux Context Display
When using SELinux filtering (-S option), sultree automatically displays the SELinux security contexts:
$ sultree -S passwd_file_t /etc
etc
group [system_u:object_r:passwd_file_t:s0]
group- [system_u:object_r:passwd_file_t:s0]
passwd [system_u:object_r:passwd_file_t:s0]
passwd- [system_u:object_r:passwd_file_t:s0]
4 files
Security Considerations
- Input validation: All paths and patterns are validated to prevent injection attacks
- Safe system calls: Uses
getfattrdirectly, no shell command execution - Path canonicalization: Prevents directory traversal attacks
- Symlink loop detection: Safely handles circular symlink references
- Permission handling: Gracefully handles permission denied errors
- Memory safety: Iterative processing prevents memory exhaustion on large trees
- Error information: Careful not to leak sensitive information in error messages
Error Handling
sultree handles various error conditions gracefully:
- Permission denied: Warns and continues with accessible files
- Broken symlinks: Logs and skips broken symbolic links
- SELinux unavailable: Clear error message if SELinux filtering requested but not available
- Invalid patterns: Validates and sanitizes all user input
- Large directories: File limit option prevents overwhelming output
Development
Project Structure
sultree/
├── src/sultree/
│ ├── __init__.py # Package initialization
│ ├── __main__.py # CLI entry point
│ ├── cli.py # Main CLI orchestration
│ ├── args.py # Argument parsing
│ ├── selinux.py # SELinux functionality
│ ├── traversal.py # Directory traversal
│ └── formatting.py # Tree output formatting
├── tests/ # Test suite
├── pyproject.toml # Modern Python packaging
├── sultree # Standalone script
└── README.md # This file
Running Tests
# Using unittest (no external dependencies)
PYTHONPATH=src python3 -m unittest discover tests -v
# Or with pytest (if available)
pytest tests/ -v
Security Scanning
# Security linting with bandit
bandit -r src/
# Dependency scanning with safety (if available)
safety check
Code Quality
# Type checking with mypy
mypy src/
# Code formatting with black
black src/ tests/
# Linting with flake8
flake8 src/
License
MIT License - see pyproject.toml for details.
Contributing
- Fork the repository
- Create a feature branch
- Add tests for new functionality
- Ensure all tests pass
- Submit a pull request
Compatibility
sultree aims for compatibility with the standard tree command while adding SELinux functionality. Most tree options are supported with the same behavior.
Supported tree Options
-a, --all: Show all files including hidden-d, --dirs-only: List directories only-l, --follow-links: Follow symbolic links-f, --full-path: Print full path prefix-x, --one-file-system: Stay on current filesystem-L level: Descend only level directories deep-P pattern: List only files matching pattern-I pattern: Ignore files matching pattern--match-dirs: Include directory names in pattern matching--ignore-case: Case insensitive pattern matching--filelimit N: Don't descend dirs with more than N files--no-report: Turn off file/directory count
SELinux Extensions
-S pattern, --selinux pattern: Show only files matching SELinux pattern
Examples
System Administration
# Find all executable files in /usr/bin
sultree -S "*_exec_t" -L 1 /usr/bin
# Audit configuration files with specific contexts
sultree -S "*_config_t" /etc
# Check for files with admin contexts
sultree -S "*admin*" /var/log
Security Analysis
# Find files with user contexts in system directories
sultree -S "user_*" /etc /var
# Look for temporary file contexts
sultree -S "*tmp*" /var /tmp
# Audit files accessible to specific domains
sultree -S "httpd_*" /var/www /etc/httpd
View source
| 1 | # sultree |
| 2 | (noun) : a wary oak |
| 3 | |
| 4 | ## what is this? |
| 5 | A SELinux-aware variant of the `tree` command that filters directory trees based on SELinux security contexts. |
| 6 | |
| 7 | ## Features |
| 8 | |
| 9 | - **Full tree compatibility**: Supports all standard `tree` command options |
| 10 | - **SELinux filtering**: Filter files and directories by SELinux security contexts using the `-S` flag |
| 11 | - **Pattern matching**: Support for wildcard patterns in SELinux context matching |
| 12 | - **Security focused**: Designed with security best practices and safe defaults |
| 13 | - **Memory efficient**: Uses iterative traversal for large directory trees |
| 14 | - **Safe error handling**: Gracefully handles permission denied and broken symlinks |
| 15 | |
| 16 | ## Requirements |
| 17 | |
| 18 | - Python 3.8+ |
| 19 | - Linux system with SELinux enabled (optional for basic tree functionality) |
| 20 | - `getfattr` utility (part of `attr` package) |
| 21 | |
| 22 | ## Installation |
| 23 | |
| 24 | ### Quick Start (No Installation) |
| 25 | |
| 26 | You can run sultree directly from the source directory: |
| 27 | |
| 28 | ```bash |
| 29 | cd sultree |
| 30 | ./sultree /path/to/directory |
| 31 | ``` |
| 32 | |
| 33 | ### Development Installation (Editable) |
| 34 | |
| 35 | ```bash |
| 36 | cd sultree |
| 37 | pip install -e .[dev] |
| 38 | ``` |
| 39 | |
| 40 | This installs sultree in editable mode, so changes to the source code are immediately available. |
| 41 | |
| 42 | ### Regular Installation |
| 43 | |
| 44 | ```bash |
| 45 | cd sultree |
| 46 | pip install . |
| 47 | ``` |
| 48 | |
| 49 | ## Usage |
| 50 | |
| 51 | ### Basic Tree Functionality |
| 52 | |
| 53 | ```bash |
| 54 | # Basic directory tree (like standard tree) |
| 55 | sultree /etc |
| 56 | |
| 57 | # Show hidden files |
| 58 | sultree -a /home/user |
| 59 | |
| 60 | # Directories only, depth limited |
| 61 | sultree -d -L 2 /usr |
| 62 | |
| 63 | # Show full paths |
| 64 | sultree -f -L 1 /var/log |
| 65 | |
| 66 | # Follow symbolic links |
| 67 | sultree -l /usr/local |
| 68 | ``` |
| 69 | |
| 70 | ### SELinux Filtering |
| 71 | |
| 72 | ```bash |
| 73 | # Show only files with specific SELinux type |
| 74 | sultree -S passwd_file_t /etc |
| 75 | |
| 76 | # Wildcard patterns in any part of context |
| 77 | sultree -S "*admin*" /var/log |
| 78 | sultree -S "httpd_*" /var/www |
| 79 | sultree -S "*_exec_t" /usr/bin |
| 80 | |
| 81 | # Multiple SELinux patterns (OR logic) |
| 82 | sultree -S passwd_file_t -S shadow_t /etc |
| 83 | |
| 84 | # Full context pattern matching |
| 85 | sultree -S "system_u:object_r:*:s0" /etc |
| 86 | |
| 87 | # Combine SELinux filtering with tree options |
| 88 | sultree -d -S httpd_exec_t -L 1 /usr/sbin |
| 89 | sultree -a -S "*_config_t" /etc |
| 90 | ``` |
| 91 | |
| 92 | ### Pattern Matching |
| 93 | |
| 94 | ```bash |
| 95 | # Include only certain file patterns |
| 96 | sultree -P "*.conf" /etc |
| 97 | |
| 98 | # Exclude backup files |
| 99 | sultree -I "*.bak" -I "*~" /home/user |
| 100 | |
| 101 | # Case-insensitive matching |
| 102 | sultree --ignore-case -P "*.TXT" /tmp |
| 103 | |
| 104 | # Apply patterns to directories too |
| 105 | sultree --match-dirs -P "*ssl*" /etc |
| 106 | ``` |
| 107 | |
| 108 | ### Advanced Options |
| 109 | |
| 110 | ```bash |
| 111 | # Limit files per directory (performance) |
| 112 | sultree --filelimit 100 /usr |
| 113 | |
| 114 | # Stay on one filesystem |
| 115 | sultree -x / |
| 116 | |
| 117 | # Suppress file/directory count |
| 118 | sultree --no-report /etc |
| 119 | ``` |
| 120 | |
| 121 | ## SELinux Context Display |
| 122 | |
| 123 | When using SELinux filtering (`-S` option), sultree automatically displays the SELinux security contexts: |
| 124 | |
| 125 | ```bash |
| 126 | $ sultree -S passwd_file_t /etc |
| 127 | etc |
| 128 | group [system_u:object_r:passwd_file_t:s0] |
| 129 | group- [system_u:object_r:passwd_file_t:s0] |
| 130 | passwd [system_u:object_r:passwd_file_t:s0] |
| 131 | passwd- [system_u:object_r:passwd_file_t:s0] |
| 132 | |
| 133 | 4 files |
| 134 | ``` |
| 135 | |
| 136 | ## Security Considerations |
| 137 | |
| 138 | - **Input validation**: All paths and patterns are validated to prevent injection attacks |
| 139 | - **Safe system calls**: Uses `getfattr` directly, no shell command execution |
| 140 | - **Path canonicalization**: Prevents directory traversal attacks |
| 141 | - **Symlink loop detection**: Safely handles circular symlink references |
| 142 | - **Permission handling**: Gracefully handles permission denied errors |
| 143 | - **Memory safety**: Iterative processing prevents memory exhaustion on large trees |
| 144 | - **Error information**: Careful not to leak sensitive information in error messages |
| 145 | |
| 146 | ## Error Handling |
| 147 | |
| 148 | sultree handles various error conditions gracefully: |
| 149 | |
| 150 | - **Permission denied**: Warns and continues with accessible files |
| 151 | - **Broken symlinks**: Logs and skips broken symbolic links |
| 152 | - **SELinux unavailable**: Clear error message if SELinux filtering requested but not available |
| 153 | - **Invalid patterns**: Validates and sanitizes all user input |
| 154 | - **Large directories**: File limit option prevents overwhelming output |
| 155 | |
| 156 | ## Development |
| 157 | |
| 158 | ### Project Structure |
| 159 | |
| 160 | ``` |
| 161 | sultree/ |
| 162 | ├── src/sultree/ |
| 163 | │ ├── __init__.py # Package initialization |
| 164 | │ ├── __main__.py # CLI entry point |
| 165 | │ ├── cli.py # Main CLI orchestration |
| 166 | │ ├── args.py # Argument parsing |
| 167 | │ ├── selinux.py # SELinux functionality |
| 168 | │ ├── traversal.py # Directory traversal |
| 169 | │ └── formatting.py # Tree output formatting |
| 170 | ├── tests/ # Test suite |
| 171 | ├── pyproject.toml # Modern Python packaging |
| 172 | ├── sultree # Standalone script |
| 173 | └── README.md # This file |
| 174 | ``` |
| 175 | |
| 176 | ### Running Tests |
| 177 | |
| 178 | ```bash |
| 179 | # Using unittest (no external dependencies) |
| 180 | PYTHONPATH=src python3 -m unittest discover tests -v |
| 181 | |
| 182 | # Or with pytest (if available) |
| 183 | pytest tests/ -v |
| 184 | ``` |
| 185 | |
| 186 | ### Security Scanning |
| 187 | |
| 188 | ```bash |
| 189 | # Security linting with bandit |
| 190 | bandit -r src/ |
| 191 | |
| 192 | # Dependency scanning with safety (if available) |
| 193 | safety check |
| 194 | ``` |
| 195 | |
| 196 | ### Code Quality |
| 197 | |
| 198 | ```bash |
| 199 | # Type checking with mypy |
| 200 | mypy src/ |
| 201 | |
| 202 | # Code formatting with black |
| 203 | black src/ tests/ |
| 204 | |
| 205 | # Linting with flake8 |
| 206 | flake8 src/ |
| 207 | ``` |
| 208 | |
| 209 | ## License |
| 210 | |
| 211 | MIT License - see pyproject.toml for details. |
| 212 | |
| 213 | ## Contributing |
| 214 | |
| 215 | 1. Fork the repository |
| 216 | 2. Create a feature branch |
| 217 | 3. Add tests for new functionality |
| 218 | 4. Ensure all tests pass |
| 219 | 5. Submit a pull request |
| 220 | |
| 221 | ## Compatibility |
| 222 | |
| 223 | sultree aims for compatibility with the standard `tree` command while adding SELinux functionality. Most `tree` options are supported with the same behavior. |
| 224 | |
| 225 | ### Supported tree Options |
| 226 | |
| 227 | - `-a, --all`: Show all files including hidden |
| 228 | - `-d, --dirs-only`: List directories only |
| 229 | - `-l, --follow-links`: Follow symbolic links |
| 230 | - `-f, --full-path`: Print full path prefix |
| 231 | - `-x, --one-file-system`: Stay on current filesystem |
| 232 | - `-L level`: Descend only level directories deep |
| 233 | - `-P pattern`: List only files matching pattern |
| 234 | - `-I pattern`: Ignore files matching pattern |
| 235 | - `--match-dirs`: Include directory names in pattern matching |
| 236 | - `--ignore-case`: Case insensitive pattern matching |
| 237 | - `--filelimit N`: Don't descend dirs with more than N files |
| 238 | - `--no-report`: Turn off file/directory count |
| 239 | |
| 240 | ### SELinux Extensions |
| 241 | |
| 242 | - `-S pattern, --selinux pattern`: Show only files matching SELinux pattern |
| 243 | |
| 244 | ## Examples |
| 245 | |
| 246 | ### System Administration |
| 247 | |
| 248 | ```bash |
| 249 | # Find all executable files in /usr/bin |
| 250 | sultree -S "*_exec_t" -L 1 /usr/bin |
| 251 | |
| 252 | # Audit configuration files with specific contexts |
| 253 | sultree -S "*_config_t" /etc |
| 254 | |
| 255 | # Check for files with admin contexts |
| 256 | sultree -S "*admin*" /var/log |
| 257 | ``` |
| 258 | |
| 259 | ### Security Analysis |
| 260 | |
| 261 | ```bash |
| 262 | # Find files with user contexts in system directories |
| 263 | sultree -S "user_*" /etc /var |
| 264 | |
| 265 | # Look for temporary file contexts |
| 266 | sultree -S "*tmp*" /var /tmp |
| 267 | |
| 268 | # Audit files accessible to specific domains |
| 269 | sultree -S "httpd_*" /var/www /etc/httpd |
| 270 | ``` |