# Contributing to OpenConnect

Contributions to OpenConnect are very welcome. You don't need to be able to write code. Testing, documentation improvements and especially translations are all extremely useful. Some specific suggestions and requests for help can be found below.

## Submitting Patches

Patches can be sent to the mailing list or directly to the author in private email. We are also experimenting with using GitLab, so please feel free to file issues and submit merge requests at https://gitlab.com/openconnect/openconnect.

When submitting patches to be included in OpenConnect, please certify that your patch meets the criteria below by including include a sign-off line in your email which looks like this:

`Signed-off-by: Random J Developer <random@developer.example.org>`

This confirms that you are permitted to submit the patch for inclusion in OpenConnect under the LGPLv2.1 licence. The full text of the certificate is as follows:

- Developer's Certificate of Origin 1.1

  By making a contribution to this project, I certify that:

  1. The contribution was created in whole or in part by me and I have the right to submit it under the open source license indicated in the file; or
  2. The contribution is based upon previous work that, to the best of my knowledge, is covered under an appropriate open source license and I have the right under that license to submit that work with modifications, whether created in whole or in part by me, under the same open source license (unless I am permitted to submit under a different license), as indicated in the file; or
  3. The contribution was provided directly to me by some other person who certified (1), (2) or (3) and I have not modified it.

  and also that:

  - I understand and agree that this project and the contribution are public and that a record of the contribution (including all personal information I submit with it, including my sign-off) is maintained indefinitely and may be redistributed consistent with this project or the open source license(s) involved.

# What needs doing?

## Translations

One of the main things needed at the present time is translations into languages other than English. All contributions will be gratefully received.

Translations for OpenConnect are maintained in the GNOME NetworkManager-openconnect module. Translations can be contributed by joining the GNOME team as described on their TranslationProject wiki page, or simply by editing one of the language files in the `po/` directory and sending the resulting patch (or file) to the mailing list.

If there are questions about the messages because the intent is not clear, or if the messages could be improved to make translation easier or better, please also feel free to ask or make suggestions on the mailing list.

## Documentation / Web Site

OpenConnect is designed with the principle that "if it needs documenting, fix it instead". That isn't to say that we don't have documentation. But if a user finds something non-obvious and has to look it up in the documentation, then that in itself is a little bit of a usability failure. Software should Just Work™.

So if you find something that is more complex than it needs to be, and you think it should Just Work™ then please don't hesitate to tell us bout it.

Any improvements to the documentation are most welcome. In particular:

- Update web site to be mobile-friendly
  The current template is definitely showing its age, and could very much do with an overhaul.

## Testing

All testing is valuable, and please do let us know if anything doesn't work when you think it should. There are some things which the regular developers don't have easy access to test, some help with testing these would be particularly welcome:

- Various authentication methods for Pulse Secure.
  Although it looked sane at first, the Pulse protocol has a lot of horrid special cases. Aside from the Host Checker most should be working, but please test and let us know if anything is missing or wrong.

## New Protocols

There are some other protocols which would be good to add to OpenConnect. Getting a new protocol to the point where it basically works to send and receive traffic is only a few hours of work, and can be very rewarding.

For some protocols we already know how they work on the wire and it's mostly just a matter of writing the code. For others we might have to observe the existing clients to learn how they work.

These would be great projects for someone to take on as a learning exercise, or perhaps even Google Summer of Code projects.

- CheckPoint VPN
  This is an IPSec-based VPN with fallback to using the SSL transport. Some discussion of OpenConnect support in this GitLab ticket, and working code contributed in MR !207.
- Cisco / Nortel IPSec VPN
  These IPSec-based protocols are already supported by vpnc to differing extents, but vpnc is no longer actively maintained. Since OpenConnect now has ESP support, and since some of these protocols also fall back to operating over TCP when UDP and native ESP aren't available, it may make sense to implement them in OpenConnect now.
- External authentication support for multiple protocols.
  Many VPNs now use SAML or other technologies to hand off the login/authentication process to a single sign-on (SSO) provider. Okta and Microsoft Azure are well known cloud-based SSO providers. We have numerous issues and merge requests labeled `External Auth/SAML/SSO`. This is an area where there is a large amount of commonal functionality across protocols, but also a large amount of variation in the details, and where we need careful help designing suitable interfaces for the interactions between OpenConnect's core code, VPN protocol-specific authentication code, and external interfaces for authentication (e.g. web browsers or graphical pop-up interfaces).

Suggestions for other protocols which OpenConnect could usefully implement are also welcome.

## Other enhancements

One of the main other improvements that would be welcome, is implementing a full WebView in the graphical clients. Currently for protocols like Juniper, OpenConnect screen-scrapes the HTML pages used for login, and attempts to make sense of them. This is The main thing that would be Other items on the TODO list include:

- WebView support in graphical clients.
  OpenConnect currently screen-scrapes the HTML login pages for protocols like Juniper, which is fragile and error-prone. It would be great if the graphical interfaces like NetworkManager could use a real WebView to show the pages, which would work with JavaScript and various other customisations that the admins often make. This might make an excellent Google Summer of Code project, or would also suit someone just trying to contribute in their spare time.
- Support for running or emulating the 'Cisco Secure Desktop' (Cisco), 'HIP' (GlobalProtect), and 'Host Checker' (Juniper/Pulse) trojans.
  OpenConnect does not yet support these trojans on Windows, whether by downloading and running trojan binaries directly, nor by invoking wrapper scripts.
- GUI for OS X, perhaps based on Tunnelblick.
- Full Android keystore support.
  OpenConnect's support for the Android keystore predates the Android keystore actually doing anything useful. We assume we can just ask for the private key and be given it. A real keystore would only allow us to perform signature operations using the key, and wouldn't just give it to us. Modern versions of Android can support this, and we should add support for it.
- Mac OS X keychain support.
  Likewise, using keys stored in the OS X keychain would be extremely useful.

## Simplify OpenConnect's approach to interacting with external scripts and program

Currently we have a vast proliferation of slightly different interfaces for OpenConnect to call scripts with slightly different interfaces, despite serving similar purposes.

### Routing and DNS configuration

- vpnc-script and vpnc-script-win.js handle this in a relatively uniform cross-protocol way, but there are still bugs tied to historical assumptions based on the Cisco AnyConnect protocol (e.g. a2b8134e and #433).
- Need ways to test these scripts on operating systems other than Linux.

### Trojans / security scanners

- Cisco CSD. Historically, this involved running a black-box binary provided by the server, then running it with a wrapper, and now running a "wrapper" script that doesn't actually invoke the binary at all but just emulates its behavior and output. For backwards-compatibility with the binary version, the script receives input via a mixture of CLI args and environment variables. It connects to the VPN server independently from the main client process. It doesn't actually return any meaningful output. Instead, the main client process must continue running in the background, reloading a "wait" URL in a loop, until the server's response to that wait URL indicates that the CSD process has completed successfully.
- Juniper/Pulse TNCC (Host Checker). Historically, this involved running a black-box Java binary provided by the server, now a "wrapper" script that emulate's the binary's behavior. The script receives input via a mixture of environment variables and standard input. It connects to the VPN server independently from the main client process, receives a token, and pipes its output back to the main client process.
- GlobalProtect HIP. The script receives input via a mixture of command-line arguments and environment variables (due to a mistaken attempt to closely copy the interface of CSD). The script does not communicate independently with the VPN server. It merely generates a blob of XML, and pipes that output back to the main client process.

### External/SAML/SSO authentication scripts

Most VPN protocols have some authentication modes which OpenConnect cannot handle on its own using its usual techniques of creating and submitting authentication forms from server-provided data (or screen-scraping). These essentially require running a full web browser environment, due to requiring JavaScript or browser plugins for the authentication to complete.

The individual VPN protocols vary substantially in how the VPN client is expected to communicate with the web browser doing the authentication:

- Cisco HPKE: the VPN client launches a browser with the URL for the SSO entry point. When the authentication is complete, the browser redirects to an HTTP GET of `http://localhost:29786/...`. This means the client has to run its own HTTP server in order to capture the output.
- GlobalProtect SAML: the VPN client either launches a browser with either (a) the URL for the SSO entry point (`saml-auth-method=REDIRECT`) or (b) an HTML page containing the SSO entry point (`saml-auth-method=POST`). The authentication is complete when the browser opens a page containing special HTTP headers. This means that the browser has to be specially instrumented in order to capture the output.
- Juniper, Pulse, F5, Fortinet: needs discovery documentation

The `open_webview` hook needs implementing for Qt/KDE and Windows GUIs.

The webview/external-browser options and API functions should perhaps be renamed to something like "external auth handler", since one of the goals and strong points of OpenConnect is to make VPN login interfaces scriptable without relying on a graphical browser in many cases.