/ceno-browser-archive

Firefox for Android (Fennec) with Ouinet integration

Primary LanguageShellOtherNOASSERTION

CENO Browser

pipeline status GitHub release (latest by date) License Weblate

CENO (Censorship.No!) is a mobile web browser, built on Mozilla's Firefox for Android (Fennec). It uses peer-to-peer technology to deliver websites to your phone and caches popular content with cooperating peers. CENO can be used to bypass Internet censorship and help others retrieve blocked pages.

▶️ Access

Get it on Play Store Get it on Paskoocheh

🚀 Features

🌴 Browse freely, anytime.
CENO is designed with internet shutdown scenarios in mind. Websites are shared by a global network of peers, and stored in a distributed cache for availability when traditional networks are blocked or go down.

🔓 Unlock the web.
Access any website. Frequently requested content is cached on the network and cannot be forcibly removed.

💲 Reduce Data Costs.
By routing user traffic through peer-to-peer networks, CENO Browser incurs less data costs while still providing users with circumvention capability.

🌐 Grow the Network, Fight Censorship.
Fight censorship by becoming a bridge! Install and run CENO Browser to instantly join the network and expand the availability of blocked websites to those in censored countries.

👐 Free and open source.
CENO Browser is powered by Ouinet, an open source library enabling third party developers to incorporate the CENO network into their apps for peer-to-peer connectivity.

👪 Contributing!

Interested in contributing to the project? Great! For starters, make sure to review and agree to the terms of our Code of Conduct

Here are some ways to help CENO Browser improve:

  • Test the app with different devices
  • Report issues in the issue tracker
  • Create a Pull Request
  • Help increasing the test coverage by contributing unit tests
  • Translate the app on Weblate

➿ Translations

Translation support is needed for:

We use Weblate for continuously-updated translations. To get started, create an account at https://weblate.org and visit https://hosted.weblate.org/projects/censorship-no/ to join the project.

🔧 Building

Developer Build

The client configuration is currently hardcoded at build time and cannot be changed at run time. You may customize a copy of the provided ouinet.sample.xml with your values, put it in the current directory as ouinet.xml (conventionally), and pass it to the invocation of build.sh with the option -x. Using ouinet.sample.xml as provided is quite pointless, but it may still help you check that the build succeeds.

Thus you can build the APK locally with the following command:

./build.sh -x ouinet.xml

By default, the latest version of the Ouinet library is automatically downloaded from Maven Central repository and used for building CENO Browser. You can also specify a different Ouinet version by setting OUINET_VERSION as follows:

OUINET_VERSION=0.20.0 ./build.sh -x ouinet.xml

You can also build Ouinet locally as part of the CENO Browser build process by using the option -o and specifying the target ABIs with the -a flag:

./build.sh -a armeabi-v7a -x ouinet.xml -o

Docker Build

This only needs to be run when the Fennec code base is upgraded:

sudo DOCKER_BUILDKIT=1 docker build --pull \
  -t registry.gitlab.com/censorship-no/ceno-browser:bootstrap .

Since that build takes significant time and bandwidth, you may want to try downloading a pre-built image (still a few gigabytes) instead:

sudo docker pull registry.gitlab.com/censorship-no/ceno-browser:bootstrap

Whenever you build or get a new bootstrap image, you need to create a derived image to run the build as a normal container user with numeric identifiers matching those of your local user (instead of root; see below for more information):

sudo DOCKER_BUILDKIT=1 docker build \
  --build-arg USER_UID=$(id -u) --build-arg USER_GID=$(id -g) \
  -t registry.gitlab.com/censorship-no/ceno-browser:bootstrap-$USER - < Dockerfile.user

If that command fails with addgroup: The GID [or UID] '<ID>' is already in use., your user's identifiers clash with the image's system ones and you will need to run the build as the container's root (see below). This is known to happen under macOS.

To actually build the software as a normal container user, run these:

mkdir -p _cache/_android _cache/_ccache _cache/_gradle # to hold globally reusable data
mkdir -p fennec && touch fennec/.finished-bootstrap # avoid bootstrap already done above

# Notes on enabling fuse inside docker
# https://stackoverflow.com/questions/48402218/fuse-inside-docker

sudo docker run \
  --rm -it \
  --user $(id -u):$(id -g) \
  --device /dev/fuse --cap-add SYS_ADMIN --security-opt apparmor:unconfined \
  --mount type=bind,source="$(pwd)",target=/usr/local/src/ouifennec \
  --mount type=bind,source="$(pwd)/_cache",target=/root/.cache \
  registry.gitlab.com/censorship-no/ceno-browser:bootstrap-$USER \
  ./build.sh [BUILD_OPTION]...

The resulting APK packages will be eventually left at the current directory. If you chose to build Ouinet with the -o option, the AAR libraries will be left there too.

You can run the last command several times: already built artifacts and cached data will be kept in the fennec build and _cache directories and reused in subsequent builds. Shall you need to build a new version of the source, you may erase the whole fennec build directory, while keeping the _cache directory should be safe. If you are asked for a root password after the container starts, the fennec/.finished-bootstrap may be missing; if it is not, please file a bug.

If you need to run commands as root in the container (e.g. to install additional packages), you can drop the --user option and its argument and use the .../ceno-browser:bootstrap image instead of the bootstrap-$USER one, but be warned that running ./build.sh as is will create root-owned files and directories in your build and cache directories which you may have problems to reuse or delete later on. To avoid that, you can run id -u and id -g at the host machine to get your user and group IDs there, then run gosu HOST_USER_ID:HOST_GROUP_ID ./build.sh in the container.

If you want to run arbitrary commands in the container, drop the ./build.sh argument at the end.

If you want to reuse the container itself, remove the --rm option and ./build.sh argument and add --name SOMETHING. After exiting the container, run sudo docker start -ia SOMETHING to start it again.

To Make A Release Build

Note: The instructions below must be done at the source directory. Invocations to ./build.sh may be direct or via the Docker container as explained above.

Before building, it is strongly recommended that you clean previous build files by running ./build.sh -c (otherwise the resulting packages may break in subtle ways). This will also remove any APK and AAR files in the current directory. If you want to keep these files, please back them up elsewhere first.

Note: If you use the Docker container and you cleaned the build files, remember to touch fennec/.finished-bootstrap again as explained above before proceeding.

  1. Choose a version number. CENO builds with the same version as the release of Firefox it is forked from, but for releases you need to specify an explicit version (like 0.0.42) to update the relevant numbers in your build. The build number which corresponds to the version code in the APK is automatically generated from the current timestamp so it does not need to be manually updated.

  2. Create a ouinet.xml file with the Ouinet client configuration that will be embedded in CENO.

  3. Choose a set of target architectures to build packages for. Currently supported ones are: armeabi-v7a (ARM 32 bit), arm64-v8a (ARM 64 bit), x86 (Intel 32 bit), x86_64 (Intel 64 bit). If none is selected, armeabi-v7a and arm64-v8a will be built.

  4. Get the upload keystore file and store it in upload-keystore.jks. Create a file upload-keystore.pass that contains the keystore password on the first line and key password on the second line. Please remember to keep these files private (you may also want to delete them after the build).

Finally run (for release v0.0.42 and ARM-only packages as an example):

./build.sh -rv 0.0.42 -x ouinet.xml \
  -a armeabi-v7a -a arm64-v8a \
  -k upload-keystore.jks -p upload-keystore.pass

Go for lunch while the build compiles.

Adding support for a language

CENO localization (l10n) is based on Mozilla repositories from https://hg.mozilla.org/l10n-central/. For a given $LOCALE (like my for generic Burmese or zh-CN for China's Chinese), we mirror its Mercurial repo to Git and create a ceno branch with CENO-specific changes, then use it as a submodule in ceno-browser.

$ apt-get install git-remote-hg
$ git clone "hg::https://hg.mozilla.org/l10n-central/$LOCALE" mozilla-l10n-$LOCALE,censorship-no
$ cd mozilla-l10n-$LOCALE,censorship-no
$ git remote rename origin upstream

Now a GitHub mirror repository https://github.com/censorship-no/mozilla-l10n-$LOCALE is created empty and all commits pushed to it:

$ git remote add origin "git@github.com:censorship-no/mozilla-l10n-$LOCALE.git"
$ git push --mirror --set-upstream origin

A commit in the repo must be found which contains adequate translations for gecko-dev. As a rule of thumb for Fennec ESR68, look for a commit like "Remove obsolete strings and reformat files" from Francesco Lodolo around 2020-08-15, and choose the previous one. Let $BASE_COMMIT be the Git hash of that commit, then it is used as a base for the ceno branch:

$ git checkout "$BASE_COMMIT"
$ git checkout -b ceno
$ git push --set-upstream origin ceno

Then the default branch of the GitHub repo is switched to ceno. Further CENO-specific changes must be pushed to that branch.

To add the language to ceno-browser:

$ cd /path/to/ceno-browser/mozilla-l10n
$ git submodule add "https://github.com/censorship-no/mozilla-l10n-$LOCALE.git" "$LOCALE"
$ git commit ...

The release build (not the debug one) will include the new language.

Configuring BitTorrent bootstrap servers

If you want to harden your CENO Browser build against the blocking of BitTorrent bootstrap servers (no relation with the Docker bootstrap image!), you may use the ouinet_bt_bootstrap_extras string in the client configuration ouinet.xml file. Just make it a space-separated string of HOST or HOST:PORT bootstrap servers, where HOST may be a host name, an IPv4 address, or a bracketed IPv6 address.

If you want to use specific bootstraps for a specific country, add a ouinet_bt_bootstrap_extras_XX string to ouinet.xml, where XX is the ISO 3166-1 alpha-2 code for the country (like US for the United States or FR for France). If there is no such country-specific string for the user's locale, CENO will revert to the generic ouinet_bt_bootstrap_extras.

❌ Uninstalling

Uninstall using adb

The ceno-browser's application package name is ie.equalit.ceno and thus to uninstall the app one would invoke:

$ adb uninstall ie.equalit.ceno

ℹ️ Additional Info

The CA certificates used by Ouinet are not the system ones because Boost.Asio can't find them. So we're using the ones from https://curl.haxx.se/docs/caextract.html and they are located in gecko-dev/mobile/android/app/src/main/assets/ceno/cacert.pem

The gecko-dev branch we've forked from (and with which it's easiest to merge again) is esr68.

📖 License

All contributions to this repository are considered to be licensed under the MIT License.