# How the cupp.py download_wordlist Function Fetches Files from FTP Repositories

> Discover how cupp.py's download_wordlist function efficiently fetches files from FTP repositories using urllib without protocol-specific code for seamless wordlist acquisition.

- Repository: [Mebus/cupp](https://github.com/Mebus/cupp)
- Tags: how-to-guide
- Published: 2026-07-03

---

**The `download_wordlist` function retrieves FTP-hosted wordlists by constructing URLs from the `dicturl` configuration entry and delegating the transfer to `urllib.request.urlopen`, which transparently handles both HTTP and FTP schemes without requiring protocol-specific code.**

The cupp.py password profiling tool includes an automated wordlist downloader that can retrieve dictionary files from FTP repositories. When users invoke the `-l` command-line flag, the `download_wordlist` function orchestrates a fetch sequence that relies on Python's standard library to handle FTP transfers transparently, requiring no external FTP libraries or manual authentication handling.

## The FTP Download Architecture

The download process relies on a three-tier architecture that separates user interaction, URL construction, and the actual network transfer.

### Configuration and URL Construction

When a user runs `python3 cupp.py -l`, the **`download_wordlist`** function (implemented around lines 998-1002 in [`cupp.py`](https://github.com/Mebus/cupp/blob/main/cupp.py)) prompts for a numeric section selection. This choice is passed to **`download_wordlist_http`** (around lines 607-613), which reads the base repository URL from the **`dicturl`** configuration entry (`CONFIG["global"]["dicturl"]` defined in [`cupp.cfg`](https://github.com/Mebus/cupp/blob/main/cupp.cfg)).

The function constructs the full download URL by concatenating the base URL with the selected category and filename:

```python
url = CONFIG["global"]["dicturl"] + category + "/" + filename

# Results in: ftp://ftp.example.com/dictionaries/english/words.gz

```

### The Generic URL Fetcher

Despite its name, **`download_http`** serves as the universal fetch mechanism. This function uses Python's **`urllib.request.urlopen`** to open the constructed URL:

```python
def download_http(url, targetfile):
    print("[+] Downloading " + targetfile + " from " + url + " ... ")
    webFile = urllib.request.urlopen(url)  # Handles http:// and ftp:// transparently

    localFile = open(targetfile, "wb")
    localFile.write(webFile.read())
    webFile.close()
    localFile.close()

```

The `urlopen` call automatically detects the FTP scheme, handles anonymous authentication if required, and returns a file-like object containing the raw bytes. This approach eliminates the need for dedicated FTP libraries like `ftplib`.

## Step-by-Step Execution Flow

The complete workflow executes as follows:

1. **User Selection**: The operator runs `cupp.py -l` and selects a dictionary section by number.
2. **URL Assembly**: `download_wordlist_http` builds the target URL using the `dicturl` base path (typically configured around line 73 in [`cupp.cfg`](https://github.com/Mebus/cupp/blob/main/cupp.cfg)).
3. **Directory Creation**: The script ensures the local `dictionaries/<category>/` directory exists via `mkdir_if_not_exists`.
4. **File Transfer**: `download_http` (lines 606-610 in [`cupp.py`](https://github.com/Mebus/cupp/blob/main/cupp.py)) streams the remote file to local storage using `urllib.request.urlopen`.
5. **Completion**: All files for the selected section are saved locally without protocol-specific handling.

## Configuring cupp for FTP Downloads

To enable FTP fetching, modify the [`cupp.cfg`](https://github.com/Mebus/cupp/blob/main/cupp.cfg) configuration file:

```ini
[downloader]
dicturl = ftp://ftp.example.com/

```

Then execute the downloader:

```bash
python3 cupp.py -l

# Select the desired number when prompted (e.g., "1")

```

The script will automatically fetch files via FTP using the same code path as HTTP downloads.

## Summary

- The **`download_wordlist`** function delegates actual file transfers to **`download_http`** in [`cupp.py`](https://github.com/Mebus/cupp/blob/main/cupp.py).
- **`urllib.request.urlopen`** handles both HTTP and FTP schemes transparently, supporting anonymous FTP authentication automatically.
- The **`dicturl`** configuration value in [`cupp.cfg`](https://github.com/Mebus/cupp/blob/main/cupp.cfg) determines whether files are fetched via HTTP or FTP.
- Downloaded files are stored in `dictionaries/<category>/` as binary streams without protocol-specific processing.
- No external FTP libraries are required; the implementation relies entirely on Python's standard library.

## Frequently Asked Questions

### Does the download_wordlist function require special FTP libraries?

No. The function relies on Python's built-in **`urllib.request.urlopen`**, which automatically handles FTP connections. The code contains no FTP-specific logic; the same `download_http` helper processes both HTTP and FTP URLs identically.

### How do I configure cupp to use a private FTP server?

Edit the **`dicturl`** entry in [`cupp.cfg`](https://github.com/Mebus/cupp/blob/main/cupp.cfg) to point to your FTP base URL (e.g., `ftp://ftp.example.com/dictionaries/`). The `download_wordlist_http` function will concatenate this base with category paths and filenames. Ensure your FTP server allows anonymous access, as the current implementation does not support authenticated FTP sessions.

### Where are downloaded wordlists stored locally?

Files are saved to **`dictionaries/<category>/`** relative to the script execution path. The **`mkdir_if_not_exists`** function creates this directory structure before `download_http` writes the binary data to the target filename.

### Can download_wordlist handle FTP authentication?

The current implementation uses `urllib.request.urlopen` without authentication parameters, which only supports **anonymous FTP** access. For authenticated FTP servers, you would need to modify the `download_http` function around lines 606-610 in [`cupp.py`](https://github.com/Mebus/cupp/blob/main/cupp.py) to include authentication headers or switch to the `ftplib` module.