diff --git a/.dockerignore b/.dockerignore
new file mode 100644
index 0000000..f961d37
--- /dev/null
+++ b/.dockerignore
@@ -0,0 +1,7 @@
+# Git and GitHub files
+/.git/
+/.github/
+
+# Local Python environment
+/venv/
+*__pycache__*
diff --git a/.github/dependabot.yml b/.github/dependabot.yml
new file mode 100644
index 0000000..253bcb7
--- /dev/null
+++ b/.github/dependabot.yml
@@ -0,0 +1,6 @@
+version: 2
+updates:
+ - package-ecosystem: github-actions
+ directory: /
+ schedule:
+ interval: daily
diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml
new file mode 100644
index 0000000..0346e90
--- /dev/null
+++ b/.github/workflows/docker.yml
@@ -0,0 +1,63 @@
+name: Build and Publish Docker Image
+
+on:
+ push:
+ pull_request:
+ workflow_dispatch:
+
+jobs:
+ build-publish:
+ strategy:
+ matrix:
+ config:
+ - local # Redirect Pretendo requests to a local server (default)
+ - wiiu # For Wii U network dumps
+ - 3ds # For 3DS network dumps
+ runs-on: ubuntu-latest
+
+ steps:
+ - name: Checkout repository
+ uses: actions/checkout@v4
+
+ - name: Set up QEMU for Docker
+ uses: docker/setup-qemu-action@v3
+
+ - name: Set up Docker Buildx
+ uses: docker/setup-buildx-action@v3
+
+ - name: Set up the ${{ matrix.config }} config
+ run: |
+ rm ./.mitmproxy/config.yaml
+ ln -s ../config-${{ matrix.config }}.yaml ./.mitmproxy/config.yaml
+
+ - name: Log into the GitHub container registry
+ if:
+ ${{ github.event != 'pull_request' && github.ref == 'refs/heads/master' }}
+ uses: docker/login-action@v3
+ with:
+ registry: ghcr.io
+ username: ${{ github.actor }}
+ password: ${{ secrets.GITHUB_TOKEN }}
+
+ - name: Extract Docker metadata
+ id: meta
+ uses: docker/metadata-action@v5
+ with:
+ images: ghcr.io/${{ github.repository }}
+ flavor: latest=${{ matrix.config == 'local' }}
+ tags: |
+ type=ref,event=branch,enable=${{ matrix.config == 'local' }}
+ type=raw,value=${{ matrix.config }}
+
+ - name: Build and push Docker image
+ id: build-and-push
+ uses: docker/build-push-action@v5
+ with:
+ context: .
+ platforms: linux/amd64,linux/arm64
+ push:
+ ${{ github.event != 'pull_request' && github.ref == 'refs/heads/master' }}
+ tags: ${{ steps.meta.outputs.tags }}
+ labels: ${{ steps.meta.outputs.labels }}
+ cache-from: type=gha
+ cache-to: type=gha,mode=max
diff --git a/.gitignore b/.gitignore
index 03866ab..a0b49e2 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,12 +1,12 @@
-# .gitignore
+# Files generated by mitmproxy, except for the main configuration
+/.mitmproxy/
+!/.mitmproxy/config.yaml
-# mitmproxy certs
-mitmproxy-ca-cert.p12
-mitmproxy-ca.p12
-mitmproxy-dhparam.pem
-mitmproxy-ca-cert.cer
-mitmproxy-ca-cert.pem
-mitmproxy-ca.pem
+# Python virtual environment
+/venv/
-# python
-__pycache__
\ No newline at end of file
+# Python cache
+__pycache__
+
+# Network dumps
+*.har
diff --git a/.mitmproxy/config.yaml b/.mitmproxy/config.yaml
new file mode 120000
index 0000000..46a5321
--- /dev/null
+++ b/.mitmproxy/config.yaml
@@ -0,0 +1 @@
+../config-local.yaml
\ No newline at end of file
diff --git a/Dockerfile b/Dockerfile
new file mode 100644
index 0000000..f0614b7
--- /dev/null
+++ b/Dockerfile
@@ -0,0 +1,47 @@
+# syntax=docker/dockerfile:1
+
+# The official mitmproxy image uses OpenSSL 3.0.x, which has older versions of
+# the SSL and TLS protocols disabled. Unfortunately, the Wii U does not support
+# newer protocols, so we need to compile a custom version of OpenSSL that has
+# the older protocols enabled and link it to the Python cryptography package.
+# Then, we copy our build of OpenSSL and cryptography to the final mitmproxy
+# container. This is definitely a hack, but it seems to work fine in a container.
+
+ARG openssl_version="1.1.1w" openssl_dir="/opt/openssl" \
+ openssl_config_dir="/usr/lib/ssl" cryptography_dir="/opt/cryptography"
+
+# We use the mitmproxy image for the build stage to ensure that all dependencies
+# are at the right versions, even though mitmproxy itself is not used here.
+FROM mitmproxy/mitmproxy:latest AS openssl-build
+ARG openssl_version openssl_dir openssl_config_dir cryptography_dir
+
+# Install build dependencies
+RUN apt update && \
+ apt install -y \
+ curl build-essential libffi-dev pkg-config
+RUN curl https://sh.rustup.rs | sh -s -- -y
+
+# Download and compile OpenSSL
+RUN curl https://www.openssl.org/source/openssl-${openssl_version}.tar.gz | tar -xvz -C /tmp
+WORKDIR /tmp/openssl-${openssl_version}
+RUN ./config --prefix=${openssl_dir} --openssldir=${openssl_config_dir} -Wl,-Bsymbolic-functions -fPIC shared
+RUN make -j $(nproc)
+RUN make install_sw
+
+# Create Python cryptography environment
+WORKDIR ${cryptography_dir}
+ENV PATH="/root/.cargo/bin:${PATH}"
+ENV OPENSSL_DIR=${openssl_dir}
+RUN python3 -m venv venv
+RUN . ${cryptography_dir}/venv/bin/activate && \
+ python3 -m pip install cryptography --no-binary cryptography -v
+
+# This is the main mitmproxy container that will be run. We use a new image so
+# the build tools are not left over in the final image.
+FROM mitmproxy/mitmproxy:latest AS mitmproxy
+ARG openssl_dir cryptography_dir
+COPY --from=openssl-build ${openssl_dir} ${openssl_dir}
+COPY --from=openssl-build ${cryptography_dir}/venv/lib /usr/local/lib
+WORKDIR /home/mitmproxy
+COPY . .
+EXPOSE 8080 8081
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..22e4cdc
--- /dev/null
+++ b/README.md
@@ -0,0 +1,218 @@
+# Mitmproxy configuration for Pretendo
+
+This repo contains configurations, scripts, and certificates for using
+`mitmproxy`/`mitmweb`/`mitmdump` to intercept traffic from Nintendo consoles,
+including the Wii U and the 3DS. It supports multiple operation modes, including
+redirecting requests to a local Pretendo Network server and collecting Wii U and
+3DS network dumps.
+
+## Collecting network dumps
+
+1. Download and install Docker using the
+ [official guide](https://docs.docker.com/get-docker/).
+2. First, make sure to **disable** Inkay or Nimbus to ensure that you are
+ connected to the official Nintendo Network servers. Then, download the right
+ NoSSL patches for your console.
+ - Wii U: Download [this patch](./ssl-patches/30_nossl.rpx) and copy it to
+ your SD card as `sd:/wiiu/environments/aroma/modules/setup/30_nossl.rpx`.
+ (Replace `aroma` with `tiramisu` if you use Tiramisu.)
+ - 3DS: Download [this patch](./ssl-patches/0004013000002F02.ips) and copy it
+ to your microSD card as `sd:/luma/sysmodules/0004013000002F02.ips`.
+3. Configure your console to connect to the proxy server.
+ - Wii U:
+ 1. Open System Settings => Internet => Connect to the Internet =>
+ Connections => (Your current internet connection) => Change Settings.
+ 2. Go to Proxy Settings => Set => OK => (Set the proxy server to your
+ computer's IP address and the port to 8082) => Confirm => Don't Use
+ Authentication.
+ - 3DS:
+ 1. Open System Settings => Internet Settings => Connection Settings =>
+ (Your current connection) => Change Settings.
+ 2. Go to Proxy Settings => Yes => Detailed Setup => (Set the proxy server
+ to your computer's IP address and the port to 8083) => OK => Don't Use
+ Authentication.
+4. Copy the command that matches your console and paste it inside a terminal
+ window to start the proxy server inside a Docker container.
+ - Wii U:
+ `docker run -it --rm -p 8082:8082 -v ./dumps:/home/mitmproxy/dumps ghcr.io/pretendonetwork/mitmproxy-nintendo:wiiu mitmdump`
+ - 3DS:
+ `docker run -it --rm -p 8083:8083 -v ./dumps:/home/mitmproxy/dumps ghcr.io/pretendonetwork/mitmproxy-nintendo:3ds mitmdump`
+5. Check your terminal window to make sure that your console is connecting to
+ the proxy server. You should see some "client connect" and "client disonnect"
+ messages.
+6. Do whatever activity you want to have in the network dump.
+7. Press `Control` and `C` in the terminal window to stop the proxy. This will
+ create a network dump HAR file in the `dumps` folder, which you can find in
+ the current folder that your terminal is running in (if you don't know, run
+ the `pwd` command).
+8. Rename the HAR file (`wiiu-latest.har` or `3ds-latest.har`) in the `dumps`
+ folder to something descriptive.
+ - **Warning: If you don't rename the dump before restarting the proxy
+ container, it will be overwritten!**
+9. Go back to step 4 for your next network dump.
+10. Upload your HAR files to any public channel in the Pretendo Network Discord
+ server to share them with the developers.
+ - **Note: Make sure to upload the HAR files directly so they can be
+ automatically deleted and reuploaded in a private channel for the
+ developers. Don't zip the folder.**
+
+When you are finished with collecting network dumps, go back into your console's
+Internet settings and disable the proxy server. For security reasons, please
+also delete the NoSSL patch you downloaded in step 2.
+
+## Local server redirection
+
+### Steps
+
+1. Choose a method below to run mitmproxy ([Docker](#running-with-docker) or
+ [local install](#running-locally)).
+2. Set up your console to connect the the proxy ([see below](#console-setup)).
+
+### Running with Docker
+
+This is the recommended way to run mitmproxy-nintendo because it always uses the
+latest image and is already set up with OpenSSL 1.1.1.
+
+1. Install Docker using the
+ [official instructions](https://docs.docker.com/get-docker/).
+2. Run a new Docker container using the
+ `ghcr.io/pretendonetwork/mitmproxy-nintendo` image.
+ - If you're not familiar with Docker, copy the `docker run ...` command from
+ [this script](./start-docker.sh) to get started. Then, open
+ in your browser to access the `mitmweb` web
+ interface for mitmproxy.
+ - Note that if you delete the `mitmproxy-pretendo-data` volume, the mitmproxy
+ server certificates will be regenerated and you will need to set up the SSL
+ patches with your custom certificates again.
+
+#### Rebuilding the Docker image
+
+If you want to make modifications to the image, you need to rebuild it locally.
+
+1. Clone this repository to your computer
+ (`git clone https://github.com/PretendoNetwork/mitmproxy-nintendo.git`).
+2. Use the `./start-docker.sh` script to build and run the container. This build
+ overwrites the version you downloaded from the container registry. This will
+ take a few minutes the first time, but it will be cached for future builds.
+ - You need to rebuild the container every time you change something here.
+
+If you want to revert your local image to the published version, run
+`docker pull ghcr.io/pretendonetwork/mitmproxy-nintendo`.
+
+### Running locally
+
+This method can be used if you don't want to install Docker or just generally
+prefer not to use Docker.
+
+Note you may run into some issues depending your OpenSSL version. Many current
+Linux distributions now use OpenSSL 3.0.0 instead of 1.1.1. OpenSSL 3.0.0
+disables protocols TLSv1.1 and earlier by default, but the console does not
+support TLSv1.2 or later. Because of this, HTTPS connections to the proxy will
+fail if mitmproxy is using OpenSSL 3.0.0.
+
+1. Install Python 3 and pip.
+2. Clone this repository to your computer
+ (`git clone https://github.com/PretendoNetwork/mitmproxy-nintendo.git`).
+3. Create a virtual environment with `python3 -m venv venv`.
+4. Activate the virtual environment with `. ./venv/bin/activate`.
+5. Install [mitmproxy](https://mitmproxy.org/) with `pip install mitmproxy`.
+ - Test that mitmproxy is working by running `mitmproxy --version`.
+ - If the OpenSSL version is above 3.0.0, the console will fail to connect via
+ HTTPS. Consider using the Docker container instead, or compile a custom
+ version of OpenSSL and Python cryptography
+ ([see below](#using-a-custom-version-of-openssl-with-mitmproxy)).
+6. Run one of the launcher scripts (i.e. `./mitmproxy`) to launch the mitmproxy
+ server.
+
+Running the launcher script will automatically load the Pretendo addon script.
+This will add the custom `pretendo_*` options to mitmproxy that allow you to
+redirect HTTP requests to your local server.
+
+## Console setup
+
+1. Install Pretendo Network patches on your console using
+ [the official guide](https://pretendo.network/docs/install):
+ - Download the patches for
+ [Wii U](https://github.com/PretendoNetwork/Inkay/releases) or
+ [3DS](https://github.com/PretendoNetwork/nimbus/releases).
+ - Skip creating a PNID on the official Pretendo server if you will be hosting
+ your own server.
+ - If you want to use Juxtaposition, you'll now need to recompile the patches
+ with your custom certificate
+ ([see below](#compiling-custom-pretendo-patches)).
+2. Configure your console to connect to the proxy using its system settings. Set
+ the console's proxy server to your computer's IP address and the port
+ to 8080.
+
+## Modifications
+
+### Compiling custom Pretendo patches
+
+The Pretendo patches normally use a Let's Encrypt certificate for HTTPS
+connections, but you can modify them to use your mitmproxy certificate instead.
+Fortunately, it's pretty easy if you use Docker to compile the patches.
+
+#### Wii U
+
+1. Clone the Inkay patcher
+ (`git clone https://github.com/PretendoNetwork/Inkay.git`)
+2. Copy your mitmproxy certificate.
+ - If you're using the Docker container, run
+ `docker run -it --rm -v mitmproxy-pretendo-data:/mnt busybox cat /mnt/mitmproxy-ca-cert.pem`.
+ - If you're running mitmproxy locally, run
+ `cat .mitmproxy/mitmproxy-ca-cert.pem`.
+3. Replace the contents of `./Inkay/data/ca.pem` with your mitmproxy
+ certificate.
+4. Run `docker build Inkay -t inkay-build` to build the Inkay build environment.
+5. Run `docker run -it --rm -v $(pwd)/Inkay:/app -w /app inkay-build` to compile
+ the patches.
+6. The compiled patch will be in `./Inkay/Inkay-pretendo.wps`. Copy this patch
+ to your SD card over FTPiiU by running
+ `ftp -u ftp://a:a@WIIU_IP/fs/vol/external01/wiiu/environments/aroma/plugins/Inkay-pretendo.wps ./Inkay/Inkay-pretendo.wps`,
+ replacing the `WIIU_IP` with your Wii U's IP address. This will replace the
+ Pretendo patch with your version with custom certificates.
+7. Reboot your Wii U.
+
+Due to Inkay's dependencies, it would be quite difficult to compile the patches
+without using Docker. If you don't want to install Docker, you could try forking
+the Inkay repository on GitHub, editing the `data/ca.pem` file in your fork, and
+building it with GitHub Actions.
+
+If you want to revert back to the regular Pretendo Network patches, re-download
+them from the Inkay repository and upload them back to your Wii U.
+
+#### 3DS
+
+Copy the `mitmproxy-ca-cert.pem` file to your microSD card as
+`sd:/3ds/juxt-prod.pem`.
+
+### Using a custom version of OpenSSL with mitmproxy
+
+See the [Dockerfile](./Dockerfile) for the necessary build steps. If you are
+doing this on your primary system, be very careful to not mess with your system
+package manager's OpenSSL installation, as this would break everything that
+relies on OpenSSL. Make sure you use a custom prefix like `/opt/openssl` when
+compiling OpenSSL 1.1.1. Use the steps to install a custom build of Python
+cryptography in your mitmproxy virtual environment.
+
+### Permanently replacing server certificates
+
+#### **_Notice: This method is deprecated and unsafe. Use a NoSSL patch instead._**
+
+If you want to intercept your console's HTTPS traffic with mitmproxy all the
+time without using the Pretendo patches, you will need to replace your console's
+server certificate with the mitmproxy certificate. Note that this is somewhat
+dangerous, as a corrupted certificate can brick your Home Menu. This should be
+safe using a coldboot CFW like CHBC, Tiramisu, or Aroma, but be aware of the
+risk.
+
+1. Back up all of your Wii U's certificates from
+ `/storage_mlc/sys/title/0005001b/10054000/content`. This backup will be
+ necessary to undo any modifications.
+2. Convert your mitmproxy certificate to the right format by running the command
+ `openssl x509 -in ./configuration/mitmproxy-ca-cert.pem -outform der -out CACERT_NINTENDO_CA_G3.der`.
+3. Upload the created `CACERT_NINTENDO_CA_G3.der` file to
+ `/storage_mlc/sys/title/0005001b/10054000/content/scerts`, replacing the
+ original file.
+
+To undo this modification, upload the backup files back to the `content` folder.
diff --git a/client-certificates/ctr-common-1.pem b/client-certificates/CTR-common.pem
similarity index 50%
rename from client-certificates/ctr-common-1.pem
rename to client-certificates/CTR-common.pem
index 43bcf7c..dbcf9b4 100644
--- a/client-certificates/ctr-common-1.pem
+++ b/client-certificates/CTR-common.pem
@@ -26,30 +26,31 @@ ahbvwpe1t3GSNOS5nBDSeCHAKLmzfnXpliA5qQZxo94RSXIVWK8hilXoFDQCL904
OGpgZnAhz4p3rcJYTq9ub8n6NYr9OJKKbWXfJY1QK4pXFVcIuAph0o/EyzDIEXuT
J4Q4b2km8uI0H4yxsQwUX9Epw6Vbujc=
-----END CERTIFICATE-----
------BEGIN RSA PRIVATE KEY-----
-MIIEpgIBAAKCAQEA81Vzs324jZwcNpbFESgDNooVTRP1TlxvYwz8bbHnJHhImjEJ
-NO29YSTpjmF7wonczooeKXfE/Ry2+ey9mk92UhzSnvuSHQ6P2zFBbcPnE8eBi73o
-DnErgixiWe1TKP1G5LvwOqrEkVmXLN/qnLrsfFp4QNyFc+PLvJ9IAfRSBwdRJHAi
-SgE9nB9eI7AGcM6DCw7+p9zEz6rNRHUVRc5I132wJpQa8aoWaqPW7LE8exEC3VSf
-DHRVPjZUMRhfoBVSi2NfiA3xYsqkv+Ct3E+bzW8y1aAQ7wIshQ/RGcLtVZE+tkoA
-znXewVLdKtcC67Vy4awhJ/BqK1tvc26qV3zIJwIDAQABAoIBAQDBTk4m9iYJoU2s
-dCPDmFTNG+8GF2fVw4rdVjCmeCDWkROkInZc7Mx4gtljub+WcOzPy1tgt/vu08Ps
-UYziLGQjoTAVCmct3CaeC8gdifZleSVJvSi/aFoXBGlxZR6ePm72QPL7uDOGAHUf
-OhboQXqi40AKzuTZhsqQYrzSiKQtXa8M0jMj3XWb7q+wLEyCtGJvUsFjfXiuxdrg
-ZMwJ3jroDkxAIatmZzzAcjbY6U78P574DQAeFJM/6KJrZXgmsPdkqEpUJWBs1Zro
-b7eEKjkM0tVfk6GrlIZgD5lhBxdyCci9UomO1JjJakKBhVeiB+HMC4sJtcJPyBdb
-ZH70dIJhAoGBAP74UyWJ/xnd12NrZrybOab5pCSYDcaoLpzghWcaxsX+AS70BpEZ
-wZU+DMxWtSfGTbVOlTlW0LEu3A9JHtisr+a3bf+ytv2zXRuDnJ3fhnFqRLRfopNs
-BEAePBUL2EkJ/8OTSsiZcmDoVyhnt14U4sleawsIi30T/KcQDtMS81YXAoGBAPRR
-F/oZcWHYNm1X8foHiPbltAji4u5M3McZT4wb3RZbWLJbUjSz/tATah36dxuT1v1z
-EwHWZ0vdN94MuIy1OnwIHvBXJy8m4Rq6VTQpzGPgy0clbZbtX3Cih+fQSvxJUe2m
-psaicsNSTtmd+btudZyG5qzILOU8afGmeB1wr3hxAoGBANZkcm3XSoUyj8FOdxXS
-pDiuI4KNxM+tbXyGIkZfMpMbkV0s3jS2ZpuakGJl6m/mhEMXL80GHfdOwsWro19o
-XYRv6vOeD9bmMj1HfrMVWFQXmmvdGrRBmJVdlwHPcu9/k+uc974ToSSxWVBlXb+j
-aksOtI2Tgs8KtmC31O9ROQHDAoGBAI0OnPdK5UmGmbX7xruCyjMyYAWZaUgInJdf
-J6xPEhCsYMNpMkc3fPEJpIT2bPpBGylt3RV8glsst+q+EXc70y51SdedmgQBQIo7
-9qGNWHJ6ASNsmp8/IZFYZXsTqZeLhX/ebf/VHsliph/Cs8LhfYoH4Pr0/+bCQLDC
-Wis1OjohAoGBAJSivkSk2MKrg/t4CqNYLBiPp0fegm9ZL3187I/leVJGXIXsNqTq
-oa6qT5JxiJRQnkw2IzfI6icl+BJYydRU3oH4X0nvl0eyjiIfG/nfn4H7ckSKdzP/
-wVBdRbcC+/PX/1WpGiJM+kXrf/vLQN1B6iihrYEkS/ZIkzFWMuuKQRvQ
------END RSA PRIVATE KEY-----
+-----BEGIN PRIVATE KEY-----
+MIIEwAIBADANBgkqhkiG9w0BAQEFAASCBKowggSmAgEAAoIBAQDzVXOzfbiNnBw2
+lsURKAM2ihVNE/VOXG9jDPxtseckeEiaMQk07b1hJOmOYXvCidzOih4pd8T9HLb5
+7L2aT3ZSHNKe+5IdDo/bMUFtw+cTx4GLvegOcSuCLGJZ7VMo/Ubku/A6qsSRWZcs
+3+qcuux8WnhA3IVz48u8n0gB9FIHB1EkcCJKAT2cH14jsAZwzoMLDv6n3MTPqs1E
+dRVFzkjXfbAmlBrxqhZqo9bssTx7EQLdVJ8MdFU+NlQxGF+gFVKLY1+IDfFiyqS/
+4K3cT5vNbzLVoBDvAiyFD9EZwu1VkT62SgDOdd7BUt0q1wLrtXLhrCEn8GorW29z
+bqpXfMgnAgMBAAECggEBAMFOTib2JgmhTax0I8OYVM0b7wYXZ9XDit1WMKZ4INaR
+E6QidlzszHiC2WO5v5Zw7M/LW2C3++7Tw+xRjOIsZCOhMBUKZy3cJp4LyB2J9mV5
+JUm9KL9oWhcEaXFlHp4+bvZA8vu4M4YAdR86FuhBeqLjQArO5NmGypBivNKIpC1d
+rwzSMyPddZvur7AsTIK0Ym9SwWN9eK7F2uBkzAneOugOTEAhq2ZnPMByNtjpTvw/
+nvgNAB4Ukz/oomtleCaw92SoSlQlYGzVmuhvt4QqOQzS1V+ToauUhmAPmWEHF3IJ
+yL1SiY7UmMlqQoGFV6IH4cwLiwm1wk/IF1tkfvR0gmECgYEA/vhTJYn/Gd3XY2tm
+vJs5pvmkJJgNxqgunOCFZxrGxf4BLvQGkRnBlT4MzFa1J8ZNtU6VOVbQsS7cD0ke
+2Kyv5rdt/7K2/bNdG4Ocnd+GcWpEtF+ik2wEQB48FQvYSQn/w5NKyJlyYOhXKGe3
+XhTiyV5rCwiLfRP8pxAO0xLzVhcCgYEA9FEX+hlxYdg2bVfx+geI9uW0COLi7kzc
+xxlPjBvdFltYsltSNLP+0BNqHfp3G5PW/XMTAdZnS9033gy4jLU6fAge8FcnLybh
+GrpVNCnMY+DLRyVtlu1fcKKH59BK/ElR7aamxqJyw1JO2Z35u251nIbmrMgs5Txp
+8aZ4HXCveHECgYEA1mRybddKhTKPwU53FdKkOK4jgo3Ez61tfIYiRl8ykxuRXSze
+NLZmm5qQYmXqb+aEQxcvzQYd907CxaujX2hdhG/q854P1uYyPUd+sxVYVBeaa90a
+tEGYlV2XAc9y73+T65z3vhOhJLFZUGVdv6NqSw60jZOCzwq2YLfU71E5AcMCgYEA
+jQ6c90rlSYaZtfvGu4LKMzJgBZlpSAicl18nrE8SEKxgw2kyRzd88QmkhPZs+kEb
+KW3dFXyCWyy36r4RdzvTLnVJ152aBAFAijv2oY1YcnoBI2yanz8hkVhlexOpl4uF
+f95t/9UeyWKmH8KzwuF9igfg+vT/5sJAsMJaKzU6OiECgYEAlKK+RKTYwquD+3gK
+o1gsGI+nR96Cb1kvfXzsj+V5UkZchew2pOqhrqpPknGIlFCeTDYjN8jqJyX4EljJ
+1FTegfhfSe+XR7KOIh8b+d+fgftyRIp3M//BUF1FtwL789f/VakaIkz6Ret/+8tA
+3UHqKKGtgSRL9kiTMVYy64pBG9A=
+-----END PRIVATE KEY-----
diff --git a/client-certificates/WiiU-account.pem b/client-certificates/WiiU-account.pem
new file mode 100644
index 0000000..62a61eb
--- /dev/null
+++ b/client-certificates/WiiU-account.pem
@@ -0,0 +1,56 @@
+-----BEGIN CERTIFICATE-----
+MIIExjCCA66gAwIBAgIBKjANBgkqhkiG9w0BAQsFADBtMQswCQYDVQQGEwJVUzET
+MBEGA1UECBMKV2FzaGluZ3RvbjEhMB8GA1UEChMYTmludGVuZG8gb2YgQW1lcmlj
+YSBJbmMuMQswCQYDVQQLEwJJUzEZMBcGA1UEAxMQTmludGVuZG8gQ0EgLSBHMzAe
+Fw0xMjA2MDcxNzI3NThaFw0zODAxMTIxNzI3NThaMIGoMQswCQYDVQQGEwJVUzET
+MBEGA1UECBMKV2FzaGluZ3RvbjEQMA4GA1UEBxMHUmVkbW9uZDEiMCAGA1UEChMZ
+TmludGVuZG8gb2YgQW1lcmljYSwgSW5jLjELMAkGA1UECxMCSVQxHTAbBgNVBAMT
+FFdpaSBVIEFjY291bnQgUHJvZCAxMSIwIAYJKoZIhvcNAQkBFhNjYUBub2Eubmlu
+dGVuZG8uY29tMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAtDA04vmM
+KuTzFm8BVPvzaEjAvPN5B7baCjgYimTznFNyrqep1L3Imc85KOUIRPLW4UT0x2ob
+mQmKJRcBl9s7/tr0lNgUUOTzFd3UfKJUSk2plYtAyCiYfddCL7cfIdGXBOMlCjcY
+Bk7/rOixyzW8psF+wmL4HkGKBu81aVaCt19yA1alydi1laA6wZOBiNvPwwPOPZnQ
+cKkIRCO+NC2VxXxJCccbQ3/LT+n+TIgegKe++yUL+eR7aJby6r1u4FHeszHuFSu2
+X32p+Wh4YFzuiwuGJWjWrMMbnYjmlaaGLVQurzOj8nGV9U1xKe6CuSVN7ddZVlcm
+Ez8onCkGM0cbOwIDAQABo4IBMzCCAS8wCQYDVR0TBAIwADAsBglghkgBhvhCAQ0E
+HxYdT3BlblNTTCBHZW5lcmF0ZWQgQ2VydGlmaWNhdGUwHQYDVR0OBBYEFJSb91rD
+nsvZF9DYVpUJuoi0S5kTMIGXBgNVHSMEgY8wgYyAFATT3tP98MjrwlmSh/sf1z5y
++O35oXGkbzBtMQswCQYDVQQGEwJVUzETMBEGA1UECBMKV2FzaGluZ3RvbjEhMB8G
+A1UEChMYTmludGVuZG8gb2YgQW1lcmljYSBJbmMuMQswCQYDVQQLEwJJUzEZMBcG
+A1UEAxMQTmludGVuZG8gQ0EgLSBHM4IBATA7BgNVHR8ENDAyMDCgLqAshipodHRw
+Oi8vY3JsLm5pbnRlbmRvLmNvbS9uaW50ZW5kby1jYS1nMy5jcmwwDQYJKoZIhvcN
+AQELBQADggEBAI7dp6gt5w5+SolgO4C2W7Ywv2uvz/6SdVr4mDPDWTH/uHCCMw+D
+yd29DT289LeQpUQAB3ojH+kCq3wrBXENBGQqTIdAoWhFiXgaUDPGkOIDmKSmRHF3
+3LKudQ7UvTQyx1W1oigZoho6p8OcsdJ+oBAjH2s1TBn5NDXlBJHWmQRAmYjnJDHR
+lmYCKmOW3ZU9XtV9CNojvxd2mt+hsT8M+Zt+JjLrPkwpWe2jZxk+V+0hjk5+yPBA
+ur9ttws8qqVfxlIfm1xosP0Pu3gxDaJz45VvKskpJFMyUN1D7mlxAnyR+DFO/NYj
+qaKn0AZyGHTutBKG0s2tTpE0xpNLKmCdyns=
+-----END CERTIFICATE-----
+-----BEGIN PRIVATE KEY-----
+MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQC0MDTi+Ywq5PMW
+bwFU+/NoSMC883kHttoKOBiKZPOcU3Kup6nUvciZzzko5QhE8tbhRPTHahuZCYol
+FwGX2zv+2vSU2BRQ5PMV3dR8olRKTamVi0DIKJh910Ivtx8h0ZcE4yUKNxgGTv+s
+6LHLNbymwX7CYvgeQYoG7zVpVoK3X3IDVqXJ2LWVoDrBk4GI28/DA849mdBwqQhE
+I740LZXFfEkJxxtDf8tP6f5MiB6Ap777JQv55HtolvLqvW7gUd6zMe4VK7Zffan5
+aHhgXO6LC4YlaNaswxudiOaVpoYtVC6vM6PycZX1TXEp7oK5JU3t11lWVyYTPyic
+KQYzRxs7AgMBAAECggEASB37LNTgCtLzkAkBqXflpdloerefuzyt6+UjvVBGSE0F
+221zhZgnz5emsv1n3+CprCOjLKUFQq0Uw19/3b17N7d+qIwLJY1c1WWhg/icb9jB
+hP7lALduwP8EmIBcT3bJUMVwr7P5Q50eq5++eSyawssy5q4hzEpC6h+Xav+a9bTr
+wgwN3FxU1T1BEotqznG+pGeek8FmQ9G3xI50+de3SGHPUZp0wJygimZTX0Ujbpqr
+YnEipm6PCna4kSAS9zqK1pPHpQc04j1MxAwU/8UKS+RYFODOKvBu97aIYmMbVGZi
+0s87E7NO9umioa8aj4HvPQmc2KwqppOfUVGP/NkhsQKBgQDbIPkIbriOhMP+/qVl
+LH2D+ciMxTnMKbhYAzYgVnYSRz9UEODTdFUidD46XXclx0OJ0kjGz27FD5A9XhAF
+OCSOdsG2sXG06ZMl9enRfBMnAikFXMKinxvB0DljsyzkujFBNcJJ0S+8V2+hIEaz
+e3gGg8O8iOmmdzCl5lteGcTYBwKBgQDSgdzJNmhEGILZmWM3JKJosXQ5Vi1I9G5N
+Jlca9ujyJiKlunBb4nBGXxuTeHXDnSBCigsqSqLJzIG2O/UbgdNixNDlGz3rlaI5
+g3oI+rdDsKPYZT8hJCxqw1xGslg8PsmdBbXY+prGaD17mjhymEM9tCA0LKd1eL41
+NUIKGo1OLQKBgGwbt2FWps0BaWULovPoYEBVYoE46Iv2ZVFevDx2C6h26CKEdTc9
+pKbr7KuE4zyLM6HyUh9rxX2JcSMlngfFLBvxMR7+KlgUCJno2iOU8CoFodFYc1oh
+32LeZQHwKwzpY1WFvUYH42IrTRKURu1T0+J67X29mnCbSy/+F0O0uO3PAoGAP4PL
+WDLAVvuGT52GYBb/odMZHEuyMjb+KO0OjyY8twNmpNaSHEdAVRtROLe54KHCIBGC
+uOn4ICdCY/fHRttvKnf0B4ymrDRj1DKlWZw8O4JKjXpPB/LgK/5yEyqwkMzpDCWy
+7pr+pCrDkk3ABmOGtlFo/hUTGdCqo2dEW8QTKqkCgYAL6PYro/q5oE8mFaqNBlUO
+8FK9Q1qvMSZxyGXAqfzJdBY77jbMtuo3ceSkJoKRtXvi5UcyCsebYqxJ7hmDx2Bi
+v66OZmYb+4RqA4w0+DzAfU6l+vVWe00nZP58kZgz+34vTCKRwk0BtxPmJw0pzgCy
+jMWTuCHskBrSGt49kzrbxQ==
+-----END PRIVATE KEY-----
diff --git a/client-certificates/WIIU_COMMON_1_CERT.pem b/client-certificates/WiiU-common.pem
similarity index 88%
rename from client-certificates/WIIU_COMMON_1_CERT.pem
rename to client-certificates/WiiU-common.pem
index c8efaec..d1152ad 100644
--- a/client-certificates/WIIU_COMMON_1_CERT.pem
+++ b/client-certificates/WiiU-common.pem
@@ -1,7 +1,3 @@
-Bag Attributes
- localKeyID: B5 CB 90 50 3A 55 5C 55 D5 93 74 82 9B 42 02 BD 44 D8 83 9B
-subject=/C=US/ST=Washington/L=Redmond/O=Nintendo of America Inc./OU=IT/CN=Wii U Common Prod 1/emailAddress=ca@noa.nintendo.com
-issuer=/C=US/ST=Washington/O=Nintendo of America Inc./OU=IS/CN=Nintendo CA - G3
-----BEGIN CERTIFICATE-----
MIIExDCCA6ygAwIBAgIBGDANBgkqhkiG9w0BAQsFADBtMQswCQYDVQQGEwJVUzET
MBEGA1UECBMKV2FzaGluZ3RvbjEhMB8GA1UEChMYTmludGVuZG8gb2YgQW1lcmlj
@@ -30,9 +26,6 @@ VXzk/33BLe386iJuLzOOqOuM025F3+CUU0isz3812Lf6GegfiNaBpfPfa2sv7EDD
WVRiGgt+bw3MJefwax05xcgLHsJZtf/N+e+84IHsM0oyEOfqlGWpFb5Tle9np8yU
kv12EjQy/Y6OJ8qkE95Ry9U1gK9t/RMm
-----END CERTIFICATE-----
-Bag Attributes
- localKeyID: B5 CB 90 50 3A 55 5C 55 D5 93 74 82 9B 42 02 BD 44 D8 83 9B
-Key Attributes:
-----BEGIN PRIVATE KEY-----
MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCoR5vkVD5lKgb2
HNRpPn25dio7Dem77REw0r7V2pObHinxWHUkPkZHfEhfOvtrsE/ZvJW28Si6SG7H
diff --git a/client-certificates/account.nintendo.net.pem b/client-certificates/account.nintendo.net.pem
deleted file mode 120000
index 86892e7..0000000
--- a/client-certificates/account.nintendo.net.pem
+++ /dev/null
@@ -1 +0,0 @@
-ctr-common-1.pem
\ No newline at end of file
diff --git a/client-certificates/account.nintendo.net.pem_wiiu b/client-certificates/account.nintendo.net.pem_wiiu
deleted file mode 120000
index 0db523c..0000000
--- a/client-certificates/account.nintendo.net.pem_wiiu
+++ /dev/null
@@ -1 +0,0 @@
-WIIU_COMMON_1_CERT.pem
\ No newline at end of file
diff --git a/client-certificates/ccs.c.shop.nintendowifi.net.pem b/client-certificates/ccs.c.shop.nintendowifi.net.pem
deleted file mode 120000
index 86892e7..0000000
--- a/client-certificates/ccs.c.shop.nintendowifi.net.pem
+++ /dev/null
@@ -1 +0,0 @@
-ctr-common-1.pem
\ No newline at end of file
diff --git a/client-certificates/ccs.wup.shop.nintendo.net.pem b/client-certificates/ccs.wup.shop.nintendo.net.pem
deleted file mode 120000
index 0db523c..0000000
--- a/client-certificates/ccs.wup.shop.nintendo.net.pem
+++ /dev/null
@@ -1 +0,0 @@
-WIIU_COMMON_1_CERT.pem
\ No newline at end of file
diff --git a/client-certificates/ecs.c.shop.nintendowifi.net.pem b/client-certificates/ecs.c.shop.nintendowifi.net.pem
deleted file mode 120000
index 86892e7..0000000
--- a/client-certificates/ecs.c.shop.nintendowifi.net.pem
+++ /dev/null
@@ -1 +0,0 @@
-ctr-common-1.pem
\ No newline at end of file
diff --git a/client-certificates/ecs.wup.shop.nintendo.net.pem b/client-certificates/ecs.wup.shop.nintendo.net.pem
deleted file mode 120000
index 0db523c..0000000
--- a/client-certificates/ecs.wup.shop.nintendo.net.pem
+++ /dev/null
@@ -1 +0,0 @@
-WIIU_COMMON_1_CERT.pem
\ No newline at end of file
diff --git a/client-certificates/nasc.nintendowifi.net.pem b/client-certificates/nasc.nintendowifi.net.pem
deleted file mode 120000
index 86892e7..0000000
--- a/client-certificates/nasc.nintendowifi.net.pem
+++ /dev/null
@@ -1 +0,0 @@
-ctr-common-1.pem
\ No newline at end of file
diff --git a/client-certificates/ninja.ctr.shop.nintendo.net.pem b/client-certificates/ninja.ctr.shop.nintendo.net.pem
deleted file mode 120000
index 86892e7..0000000
--- a/client-certificates/ninja.ctr.shop.nintendo.net.pem
+++ /dev/null
@@ -1 +0,0 @@
-ctr-common-1.pem
\ No newline at end of file
diff --git a/client-certificates/nppl.app.nintendo.net.pem b/client-certificates/nppl.app.nintendo.net.pem
deleted file mode 120000
index 0db523c..0000000
--- a/client-certificates/nppl.app.nintendo.net.pem
+++ /dev/null
@@ -1 +0,0 @@
-WIIU_COMMON_1_CERT.pem
\ No newline at end of file
diff --git a/client-certificates/nppl.c.app.nintendowifi.net.pem b/client-certificates/nppl.c.app.nintendowifi.net.pem
deleted file mode 120000
index 86892e7..0000000
--- a/client-certificates/nppl.c.app.nintendowifi.net.pem
+++ /dev/null
@@ -1 +0,0 @@
-ctr-common-1.pem
\ No newline at end of file
diff --git a/client-certificates/npvk.app.nintendo.net.pem b/client-certificates/npvk.app.nintendo.net.pem
deleted file mode 120000
index 0db523c..0000000
--- a/client-certificates/npvk.app.nintendo.net.pem
+++ /dev/null
@@ -1 +0,0 @@
-WIIU_COMMON_1_CERT.pem
\ No newline at end of file
diff --git a/client-certificates/nus.c.shop.nintendowifi.net.pem b/client-certificates/nus.c.shop.nintendowifi.net.pem
deleted file mode 120000
index 86892e7..0000000
--- a/client-certificates/nus.c.shop.nintendowifi.net.pem
+++ /dev/null
@@ -1 +0,0 @@
-ctr-common-1.pem
\ No newline at end of file
diff --git a/client-certificates/nus.wup.shop.nintendo.net.pem b/client-certificates/nus.wup.shop.nintendo.net.pem
deleted file mode 120000
index 0db523c..0000000
--- a/client-certificates/nus.wup.shop.nintendo.net.pem
+++ /dev/null
@@ -1 +0,0 @@
-WIIU_COMMON_1_CERT.pem
\ No newline at end of file
diff --git a/config-3ds.yaml b/config-3ds.yaml
new file mode 100644
index 0000000..5e2ff24
--- /dev/null
+++ b/config-3ds.yaml
@@ -0,0 +1,8 @@
+listen_port: 8083
+
+hardump: ./dumps/3ds-latest.har
+
+client_certs: ./client-certificates/CTR-common.pem
+ssl_insecure: true
+tls_version_client_min: UNBOUNDED
+tls_version_server_min: UNBOUNDED
diff --git a/config-local.yaml b/config-local.yaml
new file mode 100644
index 0000000..219d99e
--- /dev/null
+++ b/config-local.yaml
@@ -0,0 +1,24 @@
+# See https://docs.mitmproxy.org/stable/concepts-options/ for documentation
+
+listen_port: 8080
+web_port: 8081
+
+# Make sure that the right configuration files and certs are loaded
+client_certs: ./client-certificates/WiiU-common.pem
+confdir: ./.mitmproxy
+
+# Enable the Pretendo redirection script
+scripts: ["../pretendo_addon.py"]
+pretendo_redirect: true
+
+# Set up redirection to a local server
+pretendo_host: 127.0.0.1
+pretendo_host_port: 80
+pretendo_http: true
+
+# Allow self-signed certificates
+ssl_insecure: true
+
+# Allow the console to use older TLS versions
+tls_version_client_min: UNBOUNDED
+tls_version_server_min: UNBOUNDED
diff --git a/config-wiiu.yaml b/config-wiiu.yaml
new file mode 100644
index 0000000..193ad8a
--- /dev/null
+++ b/config-wiiu.yaml
@@ -0,0 +1,8 @@
+listen_port: 8082
+
+hardump: ./dumps/wiiu-latest.har
+
+client_certs: ./client-certificates/WiiU-common.pem
+ssl_insecure: true
+tls_version_client_min: UNBOUNDED
+tls_version_server_min: UNBOUNDED
diff --git a/configuration/config.yaml b/configuration/config.yaml
deleted file mode 100644
index ebef0d6..0000000
--- a/configuration/config.yaml
+++ /dev/null
@@ -1,292 +0,0 @@
-
-# Add all certificates of the upstream server to the certificate chain
-# that will be served to the proxy client, as extras. Type bool.
-add_upstream_certs_to_client_chain: false
-
-# Opposite of --ignore-hosts. Type sequence of str.
-allow_hosts: []
-
-# Strip out request headers that might cause the server to return
-# 304-not-modified. Type bool.
-anticache: false
-
-# Try to convince servers to send us un-compressed data. Type bool.
-anticomp: false
-
-# Block connections from globally reachable networks, as defined in the
-# IANA special purpose registries. Type bool.
-block_global: true
-
-# Block connections from private networks, as defined in the IANA
-# special purpose registries. This option does not affect loopback
-# addresses. Type bool.
-block_private: false
-
-# Byte size limit of HTTP request and response bodies. Understands k/m/g
-# suffixes, i.e. 3m for 3 megabytes. Type optional str.
-body_size_limit:
-
-# SSL certificates of the form "[domain=]path". The domain may include a
-# wildcard, and is equal to "*" if not specified. The file at path is a
-# certificate in PEM format. If a private key is included in the PEM, it
-# is used, else the default key in the conf dir is used. The PEM file
-# should contain the full certificate chain, with the leaf certificate
-# as the first entry. Type sequence of str.
-certs: []
-
-# Set supported ciphers for client connections using OpenSSL syntax.
-# Type optional str.
-ciphers_client:
-
-# Set supported ciphers for server connections using OpenSSL syntax.
-# Type optional str.
-ciphers_server:
-
-# Client certificate file or directory. Type optional str.
-client_certs: "./client-certificates"
-
-# Replay client requests from a saved file. Type sequence of str.
-client_replay: []
-
-# Persist command history between mitmproxy invocations. Type bool.
-command_history: true
-
-# Location of the default mitmproxy configuration files. Type str.
-confdir: ./confdir
-
-# The default content view mode. Valid values are 'auto', 'raw', 'hex',
-# 'json', 'xml/html', 'wbxml', 'javascript', 'css', 'url-encoded',
-# 'multipart form', 'image', 'query', 'protocol buffer'.
-console_default_contentview: auto
-
-# EventLog verbosity. Valid values are 'error', 'warn', 'info', 'alert',
-# 'debug'.
-console_eventlog_verbosity: info
-
-# Set the flowlist layout Valid values are 'default', 'list', 'table'.
-console_flowlist_layout: default
-
-# Focus follows new flows. Type bool.
-console_focus_follow: false
-
-# Console layout. Valid values are 'horizontal', 'single', 'vertical'.
-console_layout: single
-
-# Show layout component headers Type bool.
-console_layout_headers: true
-
-# Console mouse interaction. Type bool.
-console_mouse: true
-
-# Color palette. Valid values are 'dark', 'light', 'lowdark',
-# 'lowlight', 'solarized_dark', 'solarized_light'.
-console_palette: solarized_dark
-
-# Set transparent background for palette. Type bool.
-console_palette_transparent: false
-
-# Flow content view lines limit. Limit is enabled by default to speedup
-# flows browsing. Type int.
-content_view_lines_cutoff: 512
-
-# Enable/disable HTTP/2 support. HTTP/2 support is enabled by default.
-# Type bool.
-http2: true
-
-# PRIORITY forwarding for HTTP/2 connections. Disabled by default to
-# ensure compatibility with misbehaving servers. Type bool.
-http2_priority: false
-
-# Ignore host and forward all traffic without processing it. In
-# transparent mode, it is recommended to use an IP address (range), not
-# the hostname. In regular mode, only SSL traffic is ignored and the
-# hostname should be used. The supplied value is interpreted as a
-# regular expression and matched on the ip or the hostname. Type
-# sequence of str.
-ignore_hosts: []
-
-# Intercept filter expression. Type optional str.
-intercept:
-
-# Intercept toggle Type bool.
-intercept_active: false
-
-# Reverse Proxy: Keep the original host header instead of rewriting it
-# to the reverse proxy target. Type bool.
-keep_host_header: false
-
-# TLS key size for certificates and CA. Type int.
-key_size: 2048
-
-# Address to bind proxy to. Type str.
-listen_host: ''
-
-# Proxy service port. Type int.
-listen_port: 8080
-
-# Mode can be "regular", "transparent", "socks5", "reverse:SPEC", or
-# "upstream:SPEC". For reverse and upstream proxy modes, SPEC is host
-# specification in the form of "http[s]://host[:port]". Type str.
-mode: regular
-
-# Toggle the mitmproxy onboarding app. Type bool.
-onboarding: true
-
-# Onboarding app domain. For transparent mode, use an IP when a DNS
-# entry for the app domain is not present. Type str.
-onboarding_host: mitm.it
-
-# Port to serve the onboarding app from. Type int.
-onboarding_port: 80
-
-# Require proxy authentication. Format: "username:pass", "any" to accept
-# any user/pass combination, "@path" to use an Apache htpasswd file, or
-# "ldap[s]:url_server_ldap:dn_auth:password:dn_subtree" for LDAP
-# authentication. Type optional str.
-proxyauth:
-
-# Enable/disable experimental raw TCP support. TCP connections starting
-# with non-ascii bytes are treated as if they would match tcp_hosts. The
-# heuristic is very rough, use with caution. Disabled by default. Type
-# bool.
-rawtcp: false
-
-# Read only matching flows. Type optional str.
-readfile_filter:
-
-# Replacement patterns of the form "/pattern/regex/replacement", where
-# the separator can be any character. Type sequence of str.
-replacements: []
-
-# Read flows from file. Type optional str.
-rfile:
-
-# Stream flows to file as they arrive. Prefix path with + to append.
-# Type optional str.
-save_stream_file:
-
-# Filter which flows are written to file. Type optional str.
-save_stream_filter:
-
-# Execute a script. Type sequence of str.
-scripts: []
-
-# Start a proxy server. Enabled by default. Type bool.
-server: true
-
-# Replay server responses from a saved file. Type sequence of str.
-server_replay: []
-
-# Ignore request's content while searching for a saved flow to replay.
-# Type bool.
-server_replay_ignore_content: false
-
-# Ignore request's destination host while searching for a saved flow to
-# replay. Type bool.
-server_replay_ignore_host: false
-
-# Request's parameters to be ignored while searching for a saved flow to
-# replay. Type sequence of str.
-server_replay_ignore_params: []
-
-# Request's payload parameters (application/x-www-form-urlencoded or
-# multipart/form-data) to be ignored while searching for a saved flow to
-# replay. Type sequence of str.
-server_replay_ignore_payload_params: []
-
-# Ignore request's destination port while searching for a saved flow to
-# replay. Type bool.
-server_replay_ignore_port: false
-
-# Kill extra requests during replay. Type bool.
-server_replay_kill_extra: false
-
-# Don't remove flows from server replay state after use. This makes it
-# possible to replay same response multiple times. Type bool.
-server_replay_nopop: false
-
-# Refresh server replay responses by adjusting date, expires and last-
-# modified headers, as well as adjusting cookie expiration. Type bool.
-server_replay_refresh: true
-
-# Request headers to be considered during replay. Type sequence of str.
-server_replay_use_headers: []
-
-# Header set pattern of the form "/pattern/header/value", where the
-# separator can be any character. Type sequence of str.
-setheaders: []
-
-# Use the Host header to construct URLs for display. Type bool.
-showhost: false
-
-# Use the client's IP for server-side connections. Combine with
-# --upstream-bind-address to spoof a fixed source address. Type bool.
-spoof_source_address: false
-
-# Do not verify upstream server SSL/TLS certificates. Type bool.
-ssl_insecure: true
-
-# Path to a PEM formatted trusted CA certificate. Type optional str.
-ssl_verify_upstream_trusted_ca:
-
-# Path to a directory of trusted CA certificates for upstream server
-# verification prepared using the c_rehash tool. Type optional str.
-ssl_verify_upstream_trusted_confdir:
-
-# Set supported SSL/TLS versions for client connections. SSLv2, SSLv3
-# and 'all' are INSECURE. Defaults to secure, which is TLS1.0+. Valid
-# values are 'all', 'secure', 'SSLv2', 'SSLv3', 'TLSv1', 'TLSv1_1',
-# 'TLSv1_2'.
-ssl_version_client: secure
-
-# Set supported SSL/TLS versions for server connections. SSLv2, SSLv3
-# and 'all' are INSECURE. Defaults to secure, which is TLS1.0+. Valid
-# values are 'all', 'secure', 'SSLv2', 'SSLv3', 'TLSv1', 'TLSv1_1',
-# 'TLSv1_2'.
-ssl_version_server: secure
-
-# Set sticky auth filter. Matched against requests. Type optional str.
-stickyauth:
-
-# Set sticky cookie filter. Matched against requests. Type optional str.
-stickycookie:
-
-# Stream data to the client if response body exceeds the given
-# threshold. If streamed, the body will not be stored in any way.
-# Understands k/m/g suffixes, i.e. 3m for 3 megabytes. Type optional
-# str.
-stream_large_bodies:
-
-# Stream WebSocket messages between client and server. Messages are
-# captured and cannot be modified. Type bool.
-stream_websockets: false
-
-# Generic TCP SSL proxy mode for all hosts that match the pattern.
-# Similar to --ignore, but SSL connections are intercepted. The
-# communication contents are printed to the log in verbose mode. Type
-# sequence of str.
-tcp_hosts: []
-
-# Add HTTP Basic authentication to upstream proxy and reverse proxy
-# requests. Format: username:password. Type optional str.
-upstream_auth:
-
-# Address to bind upstream requests to. Type str.
-upstream_bind_address: ''
-
-# Connect to upstream server to look up certificate details. Type bool.
-upstream_cert: false
-
-# Limit the view to matching flows. Type optional str.
-view_filter:
-
-# Flow sort order. Valid values are 'time', 'method', 'url', 'size'.
-view_order: time
-
-# Reverse the sorting order. Type bool.
-view_order_reversed: false
-
-# Enable/disable WebSocket support. WebSocket support is enabled by
-# default. Type bool.
-websocket: true
-
diff --git a/launch b/launch
index 262f76c..ade169e 100755
--- a/launch
+++ b/launch
@@ -1,4 +1,4 @@
#!/bin/bash
-cd $(realpath --no-symlinks $(dirname $0))
-$(basename $0) --set confdir="./configuration" $*
+cd "$(realpath --no-symlinks "$(dirname "$0")")"
+$(basename "$0") --set confdir="./.mitmproxy" "$@"
diff --git a/pretendo_addon.py b/pretendo_addon.py
index 8eef8ec..33a3ca1 100644
--- a/pretendo_addon.py
+++ b/pretendo_addon.py
@@ -2,29 +2,58 @@
class PretendoAddon:
- def load(self, loader) -> None:
- loader.add_option(
- name='pretendo_redirect',
- typespec = bool,
- default = False,
- help='Redirect all requests from Nintendo to Pretendo'
- )
-
- loader.add_option(
- name='pretendo_http',
- typespec = bool,
- default = False,
- help='Sets Pretendo requests to HTTP'
- )
-
- def request(self, flow: http.HTTPFlow) -> None:
- if ctx.options.pretendo_redirect:
- if 'nintendo.net' in flow.request.host:
- flow.request.host = flow.request.host.replace('nintendo.net', 'pretendo.cc')
-
- if ctx.options.pretendo_http:
- flow.request.scheme = 'http'
-
-addons = [
- PretendoAddon()
-]
\ No newline at end of file
+ def load(self, loader) -> None:
+ loader.add_option(
+ name="pretendo_redirect",
+ typespec=bool,
+ default=True,
+ help="Redirect all requests from Nintendo to Pretendo",
+ )
+
+ loader.add_option(
+ name="pretendo_host",
+ typespec=str,
+ default="",
+ help="Host to send Pretendo requests to (keeps the original host in the Host header)",
+ )
+
+ loader.add_option(
+ name="pretendo_host_port",
+ typespec=int,
+ default=80,
+ help="Port to send Pretendo requests to (only applies if pretendo_host is set)",
+ )
+
+ loader.add_option(
+ name="pretendo_http",
+ typespec=bool,
+ default=False,
+ help="Sets Pretendo requests to HTTP (only applies if pretendo_host is set)",
+ )
+
+ def request(self, flow: http.HTTPFlow) -> None:
+ if ctx.options.pretendo_redirect:
+ if "nintendo.net" in flow.request.pretty_host:
+ flow.request.host = flow.request.pretty_host.replace(
+ "nintendo.net", "pretendo.cc"
+ )
+ elif "nintendowifi.net" in flow.request.pretty_host:
+ flow.request.host = flow.request.pretty_host.replace(
+ "nintendowifi.net", "pretendo.cc"
+ )
+
+ if ctx.options.pretendo_host and (
+ "pretendo.cc" in flow.request.pretty_host
+ or "pretendo.network" in flow.request.pretty_host
+ or "pretendo-cdn.b-cdn.net" in flow.request.pretty_host
+ ):
+ original_host = flow.request.host_header
+ flow.request.host = ctx.options.pretendo_host
+ flow.request.port = ctx.options.pretendo_host_port
+ flow.request.host_header = original_host
+
+ if ctx.options.pretendo_http:
+ flow.request.scheme = "http"
+
+
+addons = [PretendoAddon()]
diff --git a/readme.md b/readme.md
deleted file mode 100644
index 861f2fe..0000000
--- a/readme.md
+++ /dev/null
@@ -1,21 +0,0 @@
-# mitmproxy-nintedo
-
-A package for intercepting traffic from the WiiU and 3DS
-
-## Prerequisites
-
-- mitmproxy (https://mitmproxy.org/)
-- a *nix system (macos, linux, untested on WSL)
-- SSL patches for your console ([3DS SSL Patch](https://github.com/InternalLoss/3DS-SSL-Patch), [WiiU SSL Patch](https://github.com/PretendoNetwork/network-installer/tree/nossl-5.5.5))
-
-## Usage
-
-- Clone this repo to your computer
-- Run one of the launcher scripts to launch a proxy server
-- Configure your console to connect to the proxy
-
-For use with Pretendo run with the option `--scripts ./pretendo_addon.py`. This will add the custom `pretendo_redirect` and `pretendo_http` options
-
-## Known issues
-
-- WiiU eShop does not work (crashes on boot)
\ No newline at end of file
diff --git a/ssl-patches/0004013000002F02.ips b/ssl-patches/0004013000002F02.ips
new file mode 100644
index 0000000..881869a
Binary files /dev/null and b/ssl-patches/0004013000002F02.ips differ
diff --git a/ssl-patches/30_nossl.rpx b/ssl-patches/30_nossl.rpx
new file mode 100644
index 0000000..884c422
Binary files /dev/null and b/ssl-patches/30_nossl.rpx differ
diff --git a/start-docker.sh b/start-docker.sh
new file mode 100755
index 0000000..4134072
--- /dev/null
+++ b/start-docker.sh
@@ -0,0 +1,4 @@
+#! /bin/sh
+
+docker build . -t ghcr.io/pretendonetwork/mitmproxy-nintendo
+docker run -it --rm --name mitmproxy-pretendo -v mitmproxy-pretendo-data:/home/mitmproxy/.mitmproxy -p 8080:8080 -p 127.0.0.1:8081:8081 ghcr.io/pretendonetwork/mitmproxy-nintendo mitmweb --web-host 0.0.0.0