diff options
author | Aditya <bluenerd@protonmail.com> | 2023-02-27 20:04:56 +0530 |
---|---|---|
committer | Aditya <bluenerd@protonmail.com> | 2023-02-27 20:04:56 +0530 |
commit | edc449275b6c04445f58b108ca0937a87c1e8430 (patch) | |
tree | 9fd484d58145b616f29a78857cc0b1c8b1c18f05 /oh-my-zsh/plugins/shell-proxy | |
parent | 6f5424ca96c4221ef433f545642669e9c104d0ed (diff) |
add zsh
Diffstat (limited to 'oh-my-zsh/plugins/shell-proxy')
-rw-r--r-- | oh-my-zsh/plugins/shell-proxy/.editorconfig | 3 | ||||
-rw-r--r-- | oh-my-zsh/plugins/shell-proxy/README.md | 62 | ||||
-rwxr-xr-x | oh-my-zsh/plugins/shell-proxy/proxy.py | 78 | ||||
-rw-r--r-- | oh-my-zsh/plugins/shell-proxy/shell-proxy.plugin.zsh | 44 | ||||
-rwxr-xr-x | oh-my-zsh/plugins/shell-proxy/ssh-agent.py | 16 | ||||
-rwxr-xr-x | oh-my-zsh/plugins/shell-proxy/ssh-proxy.py | 36 |
6 files changed, 239 insertions, 0 deletions
diff --git a/oh-my-zsh/plugins/shell-proxy/.editorconfig b/oh-my-zsh/plugins/shell-proxy/.editorconfig new file mode 100644 index 0000000..b7c70d1 --- /dev/null +++ b/oh-my-zsh/plugins/shell-proxy/.editorconfig @@ -0,0 +1,3 @@ +[*.py] +indent_size = 4 +indent_style = space diff --git a/oh-my-zsh/plugins/shell-proxy/README.md b/oh-my-zsh/plugins/shell-proxy/README.md new file mode 100644 index 0000000..b19888c --- /dev/null +++ b/oh-my-zsh/plugins/shell-proxy/README.md @@ -0,0 +1,62 @@ +# shell-proxy plugin + +This a pure user-space program, shell-proxy setter, written in Python3 and Zsh. + +To use it, add `shell-proxy` to the plugins array in your zshrc file: + +```zsh +plugins=(... shell-proxy) +``` + +## Key features + +- Supports macOS and Linux (Ubuntu, Archlinux, etc.) +- Supports git via setting `$GIT_SSH` +- Supports ssh, sftp, scp, slogin and ssh-copy-id via setting aliases +- Built-in autocomplete + +## Usage + +### Method 1 + +Set `SHELLPROXY_URL` environment variable to the URL of the proxy server: + +```sh +SHELLPROXY_URL="http://127.0.0.1:8123" +proxy enable +``` + +### Method 2 + +Write a program file in `$HOME/.config/proxy` so that the proxy URL is defined dynamically. +Note that the program file must be executable. + +Example: + +```sh +#!/bin/bash + +if [[ "$(uname)" = Darwin ]]; then + echo "http://127.0.0.1:6152" # Surge Mac +else + echo "http://127.0.0.1:8123" # polipo +fi +``` + +### Method 3 + +Use [method 2](#method-2) but define the location of the program file by setting the +`SHELLPROXY_CONFIG` environment variable: + +```sh +SHELLPROXY_CONFIG="$HOME/.dotfiles/proxy-config" +``` + +## Reference + +- `$GIT_SSH`: <https://www.git-scm.com/docs/git#Documentation/git.txt-codeGITSSHcode> +- OpenSSH manual: <https://man.openbsd.org/ssh> + +## Maintainer + +- [@septs](https://github.com/septs) diff --git a/oh-my-zsh/plugins/shell-proxy/proxy.py b/oh-my-zsh/plugins/shell-proxy/proxy.py new file mode 100755 index 0000000..14f2944 --- /dev/null +++ b/oh-my-zsh/plugins/shell-proxy/proxy.py @@ -0,0 +1,78 @@ +#!/usr/bin/env python3 +import os +import sys +from subprocess import check_output, list2cmdline + +cwd = os.path.dirname(__file__) +ssh_agent = os.path.join(cwd, "ssh-agent.py") +proxy_env = "SHELLPROXY_URL" +proxy_config = os.environ.get("SHELLPROXY_CONFIG") or os.path.expandvars("$HOME/.config/proxy") + +usage="""shell-proxy: no proxy configuration found. + +Set `{env}` or create a config file at `{config}` +See the plugin README for more information.""".format(env=proxy_env, config=proxy_config) + +def get_http_proxy(): + default_proxy = os.environ.get(proxy_env) + if default_proxy: + return default_proxy + if os.path.isfile(proxy_config): + return check_output(proxy_config).decode("utf-8").strip() + print(usage, file=sys.stderr) + sys.exit(1) + + +def make_proxies(url: str): + proxies = {"%s_PROXY" % _: url for _ in ("HTTP", "HTTPS", "FTP", "RSYNC", "ALL")} + proxies.update({name.lower(): value for (name, value) in proxies.items()}) + proxies["GIT_SSH"] = ssh_agent + return proxies + + +def merge(mapping: dict): + return ("%s=%s" % _ for _ in mapping.items()) + + +class CommandSet: + proxies = make_proxies(get_http_proxy()) + aliases = { + _: "env __SSH_PROGRAM_NAME__=%s %s" % (_, ssh_agent) + for _ in ("ssh", "sftp", "scp", "slogin", "ssh-copy-id") + } + + def enable(self): + cmdline("export", *merge(self.proxies)) + cmdline("alias", *merge(self.aliases)) + + def disable(self): + cmdline("unset", *self.proxies.keys()) + cmdline("unalias", *self.aliases.keys()) + + def status(self): + proxies = ( + "%11s = %s" % (name, os.environ[name]) + for name in self.proxies.keys() + if name in os.environ + ) + for _ in proxies: + cmdline("echo", _) + + def usage(self): + print("usage: proxy {enable,disable,status}", file=sys.stderr) + + +def cmdline(*items): + print(list2cmdline(items)) + + +def main(): + command = CommandSet() + if len(sys.argv) == 1: + command.usage() + sys.exit(1) + getattr(command, sys.argv[1], command.usage)() + + +if __name__ == "__main__": + main() diff --git a/oh-my-zsh/plugins/shell-proxy/shell-proxy.plugin.zsh b/oh-my-zsh/plugins/shell-proxy/shell-proxy.plugin.zsh new file mode 100644 index 0000000..4fdbe93 --- /dev/null +++ b/oh-my-zsh/plugins/shell-proxy/shell-proxy.plugin.zsh @@ -0,0 +1,44 @@ +#!/usr/bin/bash +# shellcheck disable=SC1090,SC2154 + +# Handle $0 according to the standard: +# https://zdharma-continuum.github.io/Zsh-100-Commits-Club/Zsh-Plugin-Standard.html +0="${${ZERO:-${0:#$ZSH_ARGZERO}}:-${(%):-%N}}" +0="${${(M)0:#/*}:-$PWD/$0}" + +eval ' + proxy() { + # deprecate $DEFAULT_PROXY, use SHELLPROXY_URL instead + if [[ -n "$DEFAULT_PROXY" && -z "$SHELLPROXY_URL" ]]; then + echo >&2 "proxy: DEFAULT_PROXY is deprecated, use SHELLPROXY_URL instead" + SHELLPROXY_URL="$DEFAULT_PROXY" + unset DEFAULT_PROXY + fi + + # deprecate CONFIG_PROXY, use SHELLPROXY_CONFIG instead + if [[ -n "$CONFIG_PROXY" && -z "$SHELLPROXY_CONFIG" ]]; then + echo >&2 "proxy: CONFIG_PROXY is deprecated, use SHELLPROXY_CONFIG instead" + SHELLPROXY_CONFIG="$CONFIG_PROXY" + unset CONFIG_PROXY + fi + + # the proxy.py script is in the same directory as this function + local proxy="'"${0:h}"'/proxy.py" + + # capture the output of the proxy script and bail out if it fails + local output + output="$(SHELLPROXY_URL="$SHELLPROXY_URL" SHELLPROXY_CONFIG="$SHELLPROXY_CONFIG" "$proxy" "$1")" || + return $? + + # evaluate the output generated by the proxy script + source <(echo "$output") + } +' + +_proxy() { + local -r commands=('enable' 'disable' 'status') + compset -P '*,' + compadd -S '' "${commands[@]}" +} + +compdef _proxy proxy diff --git a/oh-my-zsh/plugins/shell-proxy/ssh-agent.py b/oh-my-zsh/plugins/shell-proxy/ssh-agent.py new file mode 100755 index 0000000..4ee24b7 --- /dev/null +++ b/oh-my-zsh/plugins/shell-proxy/ssh-agent.py @@ -0,0 +1,16 @@ +#!/usr/bin/env python3 +import os +import subprocess +import sys + +ssh_proxy = os.path.join(os.path.dirname(__file__), "ssh-proxy.py") + +argv = [ + os.environ.get("__SSH_PROGRAM_NAME__", "ssh"), + "-o", + "ProxyCommand={} %h %p".format(ssh_proxy), + "-o", + "Compression=yes", +] + +subprocess.call(argv + sys.argv[1:], env=os.environ) diff --git a/oh-my-zsh/plugins/shell-proxy/ssh-proxy.py b/oh-my-zsh/plugins/shell-proxy/ssh-proxy.py new file mode 100755 index 0000000..a498c84 --- /dev/null +++ b/oh-my-zsh/plugins/shell-proxy/ssh-proxy.py @@ -0,0 +1,36 @@ +#!/usr/bin/env python3 +import os +import subprocess +import sys +from urllib.parse import urlparse + +proxy = next(os.environ[_] for _ in ("HTTP_PROXY", "HTTPS_PROXY") if _ in os.environ) + +parsed = urlparse(proxy) + +proxy_protocols = { + "http": "connect", + "https": "connect", + "socks": "5", + "socks5": "5", + "socks4": "4", + "socks4a": "4", +} + +if parsed.scheme not in proxy_protocols: + raise TypeError('unsupported proxy protocol: "{}"'.format(parsed.scheme)) + +def make_argv(): + yield "nc" + if sys.platform == 'linux': + # caveats: macOS built-in netcat command not supported proxy-type + yield "-X" # --proxy-type + # Supported protocols are 4 (SOCKS v4), 5 (SOCKS v5) and connect (HTTP proxy). + # Default SOCKS v5 is used. + yield proxy_protocols[parsed.scheme] + yield "-x" # --proxy + yield parsed.netloc # proxy-host:proxy-port + yield sys.argv[1] # host + yield sys.argv[2] # port + +subprocess.call(make_argv()) |