| #!/bin/sh |
| |
| # Copyright 2015-2023 Rivoreo |
| |
| # This program is free software; you can redistribute it and/or modify it |
| # under the terms of the GNU General Public License as published by the Free |
| # Software Foundation; either version 2 of the License, or (at your option) |
| # any later version. |
| |
| # This program is distributed in the hope that it will be useful, but WITHOUT |
| # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
| # FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for |
| # more details. |
| |
| |
| base64_to_c_array() { |
| base64 -d | hexdump -v -e '1/1 "0x%02x,"' |
| } |
| |
| rsa_private_key_to_c_array() { |
| enabled= |
| while read -r line; do case "$line" in |
| "-----BEGIN RSA PRIVATE KEY-----") |
| enabled=1 |
| ;; |
| "-----END RSA PRIVATE KEY-----") |
| exit |
| ;; |
| *) |
| [ -n "$enabled" ] && printf %s\\n "$line" |
| ;; |
| esac done | base64_to_c_array |
| } |
| |
| [ -z "$CC" ] && CC=cc |
| [ -z "$CFLAGS" ] && CFLAGS="-Wall -O1" |
| |
| if [ $# != 5 ]; then |
| printf 'Usage: %s <server-address> <server-port> <server-public-key> <privileged-user-name> <client-name>\n' "$0" 1>&2 |
| exit 255 |
| fi |
| |
| client_name="$5" |
| client_program_name="client.$client_name" |
| if [ -h "$client_program_name" ] || [ -e "$client_program_name" ]; then |
| printf '%s exists\n' "$client_program_name" 1>&2 |
| exit 1 |
| fi |
| |
| set -e |
| id_dir="`mktemp -d`" |
| trap 'rm -rf "$id_dir"' EXIT |
| server_name="$1" |
| server_port="$2" |
| ssh-keygen -t rsa -b 4096 -N "" -m PEM -f "$id_dir/id_rsa" |
| public_key="`printf %s \"$3\" | base64_to_c_array`" |
| public_key="${public_key%,}" |
| private_key="`rsa_private_key_to_c_array < \"$id_dir/id_rsa\"`" |
| private_key="${private_key%,}" |
| privileged_user_name="$4" |
| $CC $CFLAGS -c base64.c syncrw.c |
| compile_and_link_sfc() { |
| $CC $CFLAGS $LDFLAGS \ |
| -D "SSHOUT_SERVER_NAME=\"$server_name\"" \ |
| -D "SSHOUT_SERVER_PORT=$server_port" \ |
| -D "SSHOUT_SERVER_PUBLIC_KEY=$public_key" \ |
| -D "SSHOUT_CLIENT_PRIVATE_KEY=$private_key" \ |
| -D "PRIVILEGED_USER_NAME=\"$privileged_user_name\"" \ |
| "$@" -x none base64.o syncrw.o -o "$client_program_name" |
| } |
| if [ -n "$STRING_TRANSLITERATION" ]; then |
| cut= |
| i=1 |
| while [ $i -lt ${#STRING_TRANSLITERATION} ]; do |
| cut="$cut?" |
| i=$((i+1)) |
| done |
| sep="${STRING_TRANSLITERATION%$cut}" |
| if [ ${#sep} != 1 ]; then |
| echo "Shell piao" 1>&2 |
| exit 1 |
| fi |
| if [ "${STRING_TRANSLITERATION#$cut}" != "$sep" ]; then |
| echo "Invalid STRING_TRANSLITERATION" 1>&2 |
| exit 1 |
| fi |
| originals="${STRING_TRANSLITERATION#?}" |
| originals="${originals%$sep*$sep}" |
| indexes="${STRING_TRANSLITERATION%?}" |
| indexes="${indexes#$sep*$sep}" |
| if [ -z "$originals" ] || [ -z "$indexes" ] || [ "$originals" = "$STRING_TRANSLITERATION" ] || [ "$indexes" = "$STRING_TRANSLITERATION" ] || [ ${#originals} != ${#indexes} ]; then |
| echo "Invalid STRING_TRANSLITERATION" 1>&2 |
| exit 1 |
| fi |
| { |
| echo "static const char *decode_string(const char *s) {" |
| echo " static char map[] = {" |
| cut= |
| i=1 |
| while [ $i -lt ${#indexes} ]; do |
| cut="$cut?" |
| i=$((i+1)) |
| done |
| while [ -n "$indexes" ]; do |
| printf " ['%c'] = '%c',\\n" "${indexes%$cut}" "${originals%$cut}" |
| indexes="${indexes#?}" |
| originals="${originals#?}" |
| cut="${cut#?}" |
| done |
| printf %s\\n \ |
| " [0] = 1 |
| }; |
| static char buffer[4096]; |
| int i; |
| if(*map == 1) { |
| *map = 0; |
| for(i = 1; i < sizeof map; i++) if(!map[i]) map[i] = i; |
| } |
| const unsigned char *up = (const unsigned char *)s; |
| i = 0; |
| do { |
| unsigned char c = up[i]; |
| buffer[i] = c < sizeof map ? map[c] : c; |
| } while(up[i++]); |
| return buffer; |
| } |
| " |
| sed -E "s/DECODE_STRING\\((\"[][ !#$%&'()*,./a-zA-Z0-9:;<=>?@^_\`{}|~+-]+\")\\)/decode_string\\(\\ |
| \\1\\ |
| \\)/g" sfc.c | sed -E "/^\".+\"\$/y$STRING_TRANSLITERATION" |
| } | compile_and_link_sfc -x c - |
| else |
| compile_and_link_sfc -D "DECODE_STRING(S)=(S)" sfc.c |
| fi |
| set -f |
| set -- `cat "$id_dir/id_rsa.pub"` |
| printf 'sshoutcfg adduser -a %s %s\n' "$2" "$client_name" |