{"id":13769108,"url":"https://github.com/dinosaure/bob","last_synced_at":"2025-05-07T15:50:42.307Z","repository":{"id":37487919,"uuid":"503925908","full_name":"dinosaure/bob","owner":"dinosaure","description":"A peer-to-peer file-transfer tool in OCaml","archived":false,"fork":false,"pushed_at":"2025-04-30T11:17:52.000Z","size":12845,"stargazers_count":139,"open_issues_count":17,"forks_count":4,"subscribers_count":5,"default_branch":"main","last_synced_at":"2025-04-30T12:42:25.641Z","etag":null,"topics":["file","p2p","security","sharing","unikernel"],"latest_commit_sha":null,"homepage":"https://bob.osau.re/","language":"OCaml","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/dinosaure.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2022-06-15T21:21:47.000Z","updated_at":"2025-04-30T11:17:57.000Z","dependencies_parsed_at":"2023-02-10T16:05:18.177Z","dependency_job_id":"09909274-9f41-49ff-aef8-bbd34447d0c5","html_url":"https://github.com/dinosaure/bob","commit_stats":{"total_commits":216,"total_committers":3,"mean_commits":72.0,"dds":0.01388888888888884,"last_synced_commit":"fb9b16bdc4f7be382cf38183ac9f6520531231b0"},"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dinosaure%2Fbob","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dinosaure%2Fbob/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dinosaure%2Fbob/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dinosaure%2Fbob/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/dinosaure","download_url":"https://codeload.github.com/dinosaure/bob/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":252910784,"owners_count":21823915,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["file","p2p","security","sharing","unikernel"],"created_at":"2024-08-03T17:00:17.511Z","updated_at":"2025-05-07T15:50:42.283Z","avatar_url":"https://github.com/dinosaure.png","language":"OCaml","funding_links":[],"categories":["Cosmopolitan"],"sub_categories":["Programs"],"readme":"\u003ch1 align=\"center\"\u003eB·o·B\u003c/h1\u003e\n\u003ch4 align=\"center\"\u003eA peer-to-peer file-transfer in OCaml\u003c/h4\u003e\n\u003chr\u003e\n\n[Bob](https://bob.osau.re/) is a **simple**, **secure** and **universal**\nprogram for transmitting a file or a folder from one person to another. The aim\nof bob is to offer the possibility to share documents without any constraints:\n- security\n- accesibility: we mainly want to provide one binary which works anywhere\n- usage\n\nThe software is available here: [bob.com][bob-com]. You can use it directly\nwithout any installation! You can check how we built `bob.com` via our website:\n[builds.osau.re](https://builds.osau.re)\n\nFor this purpose, bob uses [state-of-the-art][article] security,\n[Cosmopolitan][cosmopolitan] to ensure its accessibility on all systems and a\nsimplicity that only meets the objective of transmitting a document.\n\n### A simple example\n\n#### On Windows,\n\nThis is a simple animation of how to use `bob.com` on Windows:\n\u003cdiv align=\"center\"\u003e\nHow to send a file:\u003cbr /\u003e\n\u003cimg src=\"./img/send.gif\" alt=\"send\" width=\"50%\" /\u003e\n\nHow to receive a file (with the same password):\u003cbr /\u003e\n\u003cimg src=\"./img/receive.gif\" alt=\"receive\" width=\"50%\" /\u003e\n\u003c/div\u003e\n\n#### On other platforms,\n\nYou can compile \u0026 install bob with [opam][opam]:\n```sh\n$ opam pin add -y https://github.com/dinosaure/bob.git\n```\n\nBob has 3 sub-programs, the receiver, the sender and the relay. We will\nconcentrate on the first two:\n- `bob recv` requires a password (decided between you and the sender). Take for\n  example: revolucion-para-siempre. This program has several options like\n  accepting any sender (sharing the same password) automatically or the address\n  of the relay. An example of its use is:\n```sh\n$ bob recv revolucion-para-siempre -r $(dig +short osau.re) -y\n\u003e\u003e\u003e Received a file: my_huge_file.txt.\n\u003e\u003e\u003e ⠼   13.5 MiB    2.2 MiB/s\n```\n- `bob send` requires a document (a file or a folder) and let you to specify\n  few options: compression, password, relay address.\n```sh\n$ bob send --password revolucion-para-siempre -r $(dig +short osau.re) \\\n    --no-compression my_huge_file.txt\n\u003e\u003e\u003e [│████████████████████████████│]   13.5 MiB  / 13.54 MiB\n```\n\nAs you can see, some information is displayed and the download can begin. You\ncan let bob decide on the password if you want with regard to the sender:\n```sh\n$ bob send -r $(dig +short osau.re) my_huge_file.txt\nPassword: wei-widwagamboostu\n\u003e\u003e\u003e [│                            │]    0.0 B    / 13.54 MiB\n```\n\nAnd, by default, we always ask for confirmation from the recipients as to what\nhe/she is receiving:\n```sh\n$ bob recv -r $(dig +short osau.re) wei-widwagamboostu\nAccept from 213.245.183.59:55291 [Y/n]:\n```\n\n### Design, Protocol and Implementation\n\nIf you are interested in the implementation of bob, the protocol itself or the\ndesign of the program in general, there are some notes on this in the\ndistribution. For future contributions, it is advisable to read these\ndocuments.\n\n### Avantage of `bob`\n\n#### The relay implementation\n\nOne of the advantage of `bob` is the implementation of its relay, which simply\ntransfers information from one peer to another without altering the content.\nThe investigators of the agreement are **only** the peers and the relay does\nnot intervene **in any way** in this agreement. The sole role of the relay is\nto transfer information from one peer to another. When two peers reach an\nagreement, they notif the relay so that it can allocate a secure channel\nbetween the two peers.\n\nThe relay is therefore _blind_ to the algorithm used to reach an agreement.\nThis feature ensures that there is no compromise between peers via the relay.\n\nThe protocol itself does not allow the relay to obtain enough information to\ndecrypt your communications. Indeed, the initial exchange (the _handshake_)\nbetween the peers is an exchange that could be done without a relay. The\npurpose of the relay is:\n- to provide a stable connection\n- allow two peers to communicate with each other when they cannot directly\n  (certainly because of a proxy)\n\nThe only packet that the relay introspects is that of the receiver's refusal or\nacceptance in order to allocate a secure communication channel for the two\npeers.\n\n#### OCaml \u0026 GADTs\n\nThe state machine defined to ensure the exchange uses an feature of the OCaml\nlanguage: GADTs. From this we can encode at type level that a client cannot\ntalk to another client and a server cannot talk to another server. In this way,\nwe can prune problematic cases as errors upstream, outside the implementation\nof the so-called state machine.\n\nIndeed, the implementation of the state machine utimately focuses only on valid\ncases - namely, a receiver wanting to communicate with a sender and vice-versa.\nThis property (the duality between receiver and sender) can be _encoded_ with\ntypes and GADTs.\n\n```ocaml\ntype send = | and recv = | and relay = |\n\ntype ('a, 'b) peer =\n  | Send : (send, recv) peer\n  | Recv : (recv, send) peer\n\ntype ('from, 'to) src =\n  | Relay : (relay, 'to) src\n  | Peer  : ('from, 'non_from) peer -\u003e ('from, 'non_from) src\n\ntype ('from, 'to) dst =\n  | Relay : ('from, relay) dst\n  | Peer  : ('to, 'non_to) peer -\u003e ('non_to, 'to) dst\n\ntype ('from, 'to) packet =\n  | Hello_as_a_client : (recv, relay) packet\n  | Hello_as_a_server : (send, relay) packet\n  | Client_validator  : (recv,  send) packet\n  | Server_validator  : (send,  recv) packet\n```\n\nThis does not mean that we cannot receive a packet from a sender to a sender,\nbut we can (and should) elimimate such cases upstream of the state machine.\nAnother property is that we cannot, in OCaml and in this state machine,\nexplicitely send a packet to a sender if we are recognised as a sender.\n\n#### Unikernels and [MirageOS][mirage]\n\nBob provides 2 implementations of the relay which are very similar. One is a\npart of the executable and the user can launch its own relay _via_ `bob relay`\nand an other implementation exists as an unikernel (see [mirage/][./mirage]).\n\nThe last one lets the user compile a full operating system as a relay and\nvirtualize it with KVM for instance. You must have a machine with [KVM][kvm].\nYou must install the `mirage` tool and install `bob` first. Then, you should be\nable to craft the operating system with:\n```sh\n$ opam install mirage\n$ git clone https://github.com/dinosaure/bob\n$ mkdir bob-unikernel\n$ cp bob/mirage/* bob-unikernel/\n$ cd bob-unikernel/\n$ mirage configure -t hvt\n$ make depends\n$ mirage build\n$ ls dist/bob.hvt\ndist/bob.hvt\n```\n\nAn image `bob.hvt` is crafted and it can be launched with [Solo5][solo5] and\n[albatross][albatross]. Albatross is available _via_ `apt` if you want:\n```sh\n$ wget -q -O - https://apt.robur.coop/gpg.pub | apt-key add -\n$ echo \"deb https://apt.robur.coop ubuntu-20.04 main\" \u003e\u003e /etc/apt/sources.list\n$ sudo apt update\n$ sudo apt install solo5 albatross\n```\n\n##### Networks and unikernels\n\nFor OS virtualization, you usually requires a bridge:\n```\n$ cat \u003e\u003e/etc/network/interfaces \u003c\u003cEOF\n\nauto service\niface service inet static\n  address 10.0.0.1\n  netmask 255.255.255.0\n  broadcast 10.0.0.255\n  bridge_ports none\n  bridge_stp off\n  bridge_fd 0\n  bridge_maxwait 0\nEOF\n$ systemctl restart networking\n```\n\nFinally, you need to let the unikernel to communicate with Internet and let\npeople to communicate with your unikernel:\n```sh\n$ cat \"1\" \u003e /proc/sys/net/ipv4/ip_forward\n$ iptables -A FORWARD -o service -m conntrack --ctstate RELATED,ESTABLISHED \\\n    -j ACCEPT\n$ iptables -A FORWARD -i service ! -o service -j ACCEPT\n$ iptables -A FORWARD -i service -o service -j ACCEPT\n$ iptables -t nat -A POSTROUTING -s 10.0.0.0/24 ! -o service \\\n    -j MASQUERADE\n$ iptables -N BOB\n$ iptables -A BOB -d 10.0.0.2/32 ! -i service -o service \\\n    -p tcp -m tcp --dport 9000 -j ACCEPT\n$ iptables -A BOB -d 10.0.0.2/32 ! -i service -o service \\\n    -p tcp -m tcp --dport 9001 -j ACCEPT\n$ iptables -A FORWARD -o service -j BOB\n$ iptables -t nat -N BOB\n$ iptables -t nat -A PREROUTING -m addrtype --dst-type LOCAL -j BOB\n$ iptables -t nat -A BOB ! -s 10.0.0.2/32 \\\n    -p tcp -m tcp --dport 9000 -j DNAT --to-destination 10.0.0.2:9000\n$ iptables -t nat -A BOB ! -s 10.0.0.2/32 \\\n    -p tcp -m tcp --dport 9001 -j DNAT --to-destination 10.0.0.2:9000\n```\n\n##### Launch the unikernel\n\nYou can launch the unikernel with `albatross` with:\n```sh\n$ albatross-client create --net=service \\\n    --arg=\"--ipv4=10.0.0.2/24\"\n    --arg=\"--ipv4-gateway=10.0.0.1\" bob bob.hvt\n```\n\nLocally, you are able to communicate with your relay _via_ the `-r` option:\n```sh\n$ bob send -r \u003cmy-public-ip\u003e:9000\nPassword: shoacquis-feursonsindlebu\n\n$ bob -r \u003cmy-public-ip\u003e:9000 shoacquis-feursonsindlebu\nAccept from \u003cserver-identity\u003e [Y/n]: Y\nHandshake is done with \u003cserver-identity\u003e\n```\n\n#### Reproducible builds\n\nThe version you can download of `bob.com` was produced in such a context that\nyou can reproduce the same binary in the same context. This is called software\nreproducibility. We provide an infrastructure (developed by [robur.coop][robur])\n[builds.osau.re](https://builds.osau.re) that checks the reproducibility of the\nsoftware every day.\n\n#### [Esperanto][esperanto], [Cosmopolitan][cosmopolitan] and Windows support\n\nCurrently, the `bob` executable can be compiled with the `esperanto` toolchain.\nBy this way, we are able to deliver a `bob.com` which works _anywhere_. The\nstatus of it is experimental. However, few tweak on some libraries (specially\n`mirage-crypto`) are needed to be able to compile `bob` with this _toolchain_.\n\nThe final executable, the `bob.com` seems to work on PowerShell (Windows) and\nobviously Linux.\n\nA CI exists which try to compile `bob` with Esperanto and Cosmopolitan. The\nbuilded artifact is available into the GitHub action which built the\nexecutable. Any users can download this artifact (see Actions and the last\ngreen GitHub Action, you will find a `bob.com` artifact) and execute it on\ntheir computer - there should be no prerequisites.\n\n[spoke]: https://github.com/dinosaure/spoke\n[article]: https://blog.osau.re/articles/spoke.html\n[mirage]: https://mirage.io/\n[kvm]: https://en.wikipedia.org/wiki/Kernel-based_Virtual_Machine\n[solo5]: https://github.com/Solo5/solo5\n[albatross]: https://github.com/hannesm/albatross\n[esperanto]: https://github.com/dinosaure/esperanto\n[cosmopolitan]: https://github.com/jart/cosmopolitan\n[opam]: https://opam.ocaml.org/\n[robur]: https://robur.coop/\n[bob-com]: https://builds.osau.re/job/bob/build/latest/f/bin/bob.com\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdinosaure%2Fbob","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdinosaure%2Fbob","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdinosaure%2Fbob/lists"}