├── VERSION ├── .gitmodules ├── data ├── templates │ ├── us │ │ └── TOS.txt │ └── fr │ │ └── TOS.txt ├── sshgate.conf └── sshgate.setup ├── tests ├── sshgate.test.conf ├── coverage ├── usergroup.testcase ├── user.testcase ├── access.testcase ├── target.testcase └── test.sh ├── bin ├── archive-log.sh ├── core │ ├── help.func │ ├── target-known_hosts.func │ ├── usergroup.func │ ├── sshgate.core │ ├── target-sshkey.func │ ├── record.func │ ├── target-access.func │ ├── target.func │ ├── target-ssh.func │ └── user.func ├── sshgate-bridge └── sshgate-cli ├── README └── COPYING /VERSION: -------------------------------------------------------------------------------- 1 | 0.3-beta 2 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "lib"] 2 | path = lib 3 | url = git://github.com/Tauop/ScriptHelper.git 4 | -------------------------------------------------------------------------------- /data/templates/us/TOS.txt: -------------------------------------------------------------------------------- 1 | ******************************************************************************* 2 | All actions you perform on servers, which you connect with the gateway sshGate 3 | to, are recorded. By the way, sshGate administrators are able to diagnose a 4 | problem on a server, and find which command results in the malfunction. 5 | ******************************************************************************* 6 | 7 | Do you accept those Term of Service (TOS) ? 8 | -------------------------------------------------------------------------------- /data/templates/fr/TOS.txt: -------------------------------------------------------------------------------- 1 | ******************************************************************************* 2 | Toutes les actions que vous réalisez sur les serveurs sur lesquels vous vous 3 | connectez avec la passerelle sshGate sont enregistrées. Cela permet notamment 4 | aux administrateurs de la passerelle sshGate de pouvoir diagnostiquer un 5 | problème sur un serveur, et de trouver la mauvaise manipulation dont le 6 | dysfonctionnement résulte. 7 | 8 | Pour toute information sur vos droits et les traitements automatiques 9 | réalisées, vous pouvez consulter la note de service "CNIL", notre responsable 10 | juridique ou les délégués du personnel. 11 | 12 | ******************************************************************************* 13 | 14 | Acceptez-vous ces Conditions Générale d'Utilisation (CGU) ? 15 | -------------------------------------------------------------------------------- /tests/sshgate.test.conf: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright (c) 2010 Linagora 3 | # Patrick Guiran . 18 | # 19 | 20 | SSHGATE_VERSION='%% __SSHGATE_VERSION__ %%' # set by build.sh 21 | SSHGATE_BUILD='%% __SSHGATE_BUILD__ %%' # set by build.sh 22 | 23 | # where is installed sshGate ? 24 | SSHGATE_DIRECTORY='/opt/sshgate' 25 | 26 | # local unix account for using sshgate 27 | SSHGATE_GATE_ACCOUNT='sshgate' 28 | SSHGATE_ALLOW_REMOTE_COMMAND='Y' 29 | SSHGATE_USE_REMOTE_ADMIN_CLI='Y' 30 | SSHGATE_USERS_MUST_ACCEPT_TOS='Y' 31 | 32 | # editor to use when editing files 33 | SSHGATE_EDITOR='vim' 34 | 35 | # default path where files where sent to the target host 36 | SSHGATE_TARGETS_SCP_PATH='~' 37 | 38 | # default user to use when login to a target host 39 | SSHGATE_TARGETS_DEFAULT_SSH_LOGIN='root' 40 | 41 | # to activate recap email sending 42 | SSHGATE_MAIL_SEND='N' 43 | SSHGATE_MAIL_TO='sshgate@linagora.com' 44 | SSHGATE_MAIL_SUBJECT='[sshGate] modifications report' 45 | -------------------------------------------------------------------------------- /data/sshgate.conf: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright (c) 2010 Linagora 3 | # Patrick Guiran . 18 | # 19 | 20 | SSHGATE_VERSION='%% __SSHGATE_VERSION__ %%' # set by build.sh 21 | SSHGATE_BUILD='%% __SSHGATE_BUILD__ %%' # set by build.sh 22 | 23 | # where is installed sshGate ? /!\ can't be modified after installation /!\ 24 | SSHGATE_DIRECTORY='/opt/sshgate' 25 | 26 | # where sshGate can get ScriptHelper ? /!\ can't be modified after installation /!\ 27 | SCRIPT_HELPER_DIRECTORY='/opt/sshgate/bin/lib' 28 | 29 | # local unix account for using sshgate /!\ can't be modified after installation /!\ 30 | SSHGATE_GATE_ACCOUNT='sshgate' 31 | 32 | SSHGATE_ALLOW_REMOTE_COMMAND='Y' 33 | SSHGATE_USE_REMOTE_ADMIN_CLI='Y' 34 | SSHGATE_SUDO_WITH_NOPASSWORD='Y' 35 | SSHGATE_USERS_MUST_ACCEPT_TOS='Y' 36 | 37 | # editor to use when editing files. leave it empty to use ${EDITOR} 38 | SSHGATE_EDITOR='' 39 | 40 | # default path where files where sent to the target host 41 | SSHGATE_TARGETS_SCP_PATH='~' 42 | 43 | # default user to use when login to a target host 44 | SSHGATE_TARGETS_DEFAULT_SSH_LOGIN='root' 45 | 46 | SSHGATE_DEFAULT_LANGUAGE='us' 47 | 48 | # to activate recap email sending 49 | SSHGATE_MAIL_SEND='N' 50 | SSHGATE_MAIL_TO='you@yourdomain.tld' 51 | SSHGATE_MAIL_SUBJECT='[sshGate] modifications report' 52 | -------------------------------------------------------------------------------- /bin/archive-log.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # 3 | # Copyright (c) 2010 Linagora 4 | # Patrick Guiran 5 | # http://github.com/Tauop/sshGate 6 | # 7 | # sshGate is free software, you can redistribute it and/or modify 8 | # it under the terms of the GNU General Public License as 9 | # published by the Free Software Foundation; either version 2 of 10 | # the License, or (at your option) any later version. 11 | # 12 | # sshGate is distributed in the hope that it will be useful, 13 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | # GNU General Public License for more details. 16 | # 17 | # You should have received a copy of the GNU Lesser General Public License 18 | # along with this program. If not, see . 19 | # 20 | 21 | if [ $# -eq 1 ]; then 22 | month_ago="$1" 23 | fi 24 | 25 | # load dependencies 26 | load() { 27 | local var= value= file= 28 | 29 | var="$1"; file="$2" 30 | value=$( eval "echo \"\${${var}:-}\"" ) 31 | 32 | [ -n "${value}" ] && return 1; 33 | if [ -f "${file}" ]; then 34 | . "${file}" 35 | else 36 | echo "ERROR: Unable to load ${file}" 37 | exit 2 38 | fi 39 | return 0; 40 | } 41 | 42 | 43 | load SSHGATE_DIRECTORY '/etc/sshgate.conf' 44 | load SCRIPT_HELPER_DIRECTORY '/etc/ScriptHelper.conf' 45 | 46 | load __SSHGATE_SETUP__ "${SSHGATE_DIRECTORY}/data/sshgate.setup" 47 | load __LIB_RANDOM__ "${SCRIPT_HELPER_DIRECTORY}/random.lib.sh" 48 | 49 | archive="${SSHGATE_DIR_ARCHIVE}/$( date +%Y%m --date "-${month_ago} month" )_log.tar" 50 | tmp_file="/tmp/files.$(RANDOM)" 51 | 52 | find "${SSHGATE_DIR_LOGS_TARGETS}" -name "$( date +%Y%m --date "-${month_ago} month" )*" > "${tmp_file}" 53 | find "${SSHGATE_DIR_LOGS_TARGETS}" -name 'global.log' >> "${tmp_file}" 54 | 55 | tar cf "${archive}" "${SSHGATE_DIR_LOGS}/sshgate.log" 56 | cat "${tmp_file}" | xargs tar rf "${archive}" 57 | gzip "${archive}" 58 | 59 | #cat "${tmp_file}" | xargs rm -f 60 | #rm -f "${SSHGATE_DIR_LOGS}/sshgate.log" 61 | rm -f "${tmp_file}" 62 | 63 | exit 0; 64 | -------------------------------------------------------------------------------- /tests/coverage: -------------------------------------------------------------------------------- 1 | can't be tested : 2 | - usergroup access notify 3 | - target [@] access info 4 | 5 | user.testcase : 6 | - user list 7 | - user add mail 8 | - user del 9 | - user build auth_keys 10 | - user display conf 11 | - user set conf 12 | - user del conf 13 | - user edit sshkey 14 | - user display sshkey 15 | - user update auth_keys 16 | 17 | target.testcase 18 | - target list 19 | - target add [@] 20 | - target add [@] with proxy [@] 21 | - target add [@] via [@] 22 | - target del 23 | - target alias list 24 | - target ssh test all 25 | - target ssh install all key 26 | - target ssh edit config 27 | - target ssh display config 28 | - target ssh update known_hosts 29 | - target rename 30 | - target realname 31 | - target add alias 32 | - target del alias 33 | - target list alias 34 | - target display conf 35 | - target set conf 36 | - target del conf 37 | - target ssh test 38 | - target ssh list logins 39 | - target ssh add login 40 | - target ssh del login 41 | - target [@] ssh edit config 42 | - target [@] ssh display config 43 | - target [@] ssh display full config 44 | - target ssh display key 45 | - target ssh edit key 46 | - target ssh install key 47 | - target ssh use default key 48 | - target ssh update known_hosts 49 | 50 | usergroup.testcase 51 | - user list usergroups 52 | - usergroup add 53 | - usergroup del 54 | - usergroup list users 55 | - usergroup add user 56 | - usergroup del user 57 | - usergroup list targets 58 | - usergroup access info 59 | 60 | access.testcase 61 | - user list targets 62 | - user has access 63 | - user access info 64 | - user access notify 65 | - target [@] access list users 66 | - target [@] access add user 67 | - target [@] access del user 68 | - target [@] access list usergroups 69 | - target [@] access add usergroup 70 | - target [@] access del usergroup 71 | -------------------------------------------------------------------------------- /tests/usergroup.testcase: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright (c) 2010 Linagora 3 | # Patrick Guiran 4 | # http://github.com/Tauop/ScriptHelper 5 | # 6 | # ScriptHelper is free software, you can redistribute it and/or modify 7 | # it under the terms of the GNU General Public License as 8 | # published by the Free Software Foundation; either version 2 of 9 | # the License, or (at your option) any later version. 10 | # 11 | # ScriptHelper is distributed in the hope that it will be useful, 12 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | # GNU General Public License for more details. 15 | # 16 | # You should have received a copy of the GNU Lesser General Public License 17 | # along with this program. If not, see . 18 | # 19 | # -------------------------------------------------------------------------- 20 | 21 | mDOTHIS 'Generate usergroup tests' 22 | 23 | cat >"${expected_test_file}" < usergroup list 25 | 26 | sshGate > user add pguiran mail pguiran@linagora.com 27 | $(cat "${sshkey_pub_test_file}" | while read line ; do echo "<<-${line}"; done; echo "->>" ) 28 | sshGate > user add scourtois mail simon@courtois.fr 29 | $(cat "${sshkey_pub_test_file}" | while read line ; do echo "<<-${line}"; done; echo "->>" ) 30 | sshGate > user list 31 | pguiran 32 | scourtois 33 | sshGate > usergroup add OSSA 34 | sshGate > usergroup add LRS 35 | sshGate > usergroup list 36 | LRS 37 | OSSA 38 | sshGate > usergroup LRS 39 | sshGate [usergroup LRS]> add user pguiran 40 | sshGate [usergroup LRS]> add user scourtois 41 | sshGate [usergroup LRS]> quit 42 | sshGate > usergroup OSSA add user scourtois 43 | sshGate > usergroup OSSA add user pguiran 44 | sshGate > usergroup OSSA list users 45 | pguiran 46 | scourtois 47 | sshGate > usergroup OSSA del user scourtois 48 | sshGate > usergroup OSSA list users 49 | pguiran 50 | sshGate > usergroup LRS list users 51 | pguiran 52 | scourtois 53 | sshGate > user pguiran list usergroups 54 | LRS 55 | OSSA 56 | sshGate > user scourtois list usergroups 57 | LRS 58 | sshGate > usergroup del OSSA 59 | sshGate > user pguiran list usergroups 60 | LRS 61 | sshGate > usergroup list 62 | LRS 63 | sshGate > usergroup LRS list users 64 | pguiran 65 | scourtois 66 | sshGate > user del scourtois 67 | sshGate > usergroup LRS list users 68 | pguiran 69 | sshGate > exit 70 | EOF 71 | 72 | grep -E '^(<<=|<<-|->>|sshGate [^>]*>)' < "${expected_test_file}" \ 73 | | sed -e 's/^sshGate [^>]*> //' > "${input_test_file}" 74 | 75 | tmp_file="${expected_test_file}.$(RANDOM)" 76 | grep -v -E '^(<<=|<<-|->>)' < "${expected_test_file}" > "${tmp_file}" 77 | mv "${tmp_file}" "${expected_test_file}" 78 | 79 | mOK 80 | 81 | # -------------------------------------------------------------------------- 82 | mDOTHIS 'Launch usergroup tests' 83 | ASK_SET_AUTOANSWER_FILE "${input_test_file}" 84 | ( CLI_RUN > "${output_test_file}" ) 85 | result_diff=$( diff -au "${expected_test_file}" "${output_test_file}" ) 86 | if [ $? -eq 0 ]; then 87 | mOK 88 | else 89 | echo "Test Failed" 90 | echo "==========================================================" 91 | echo "${result_diff}" 92 | echo "==========================================================" 93 | fi 94 | -------------------------------------------------------------------------------- /data/sshgate.setup: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright (c) 2010 Linagora 3 | # Patrick Guiran . 18 | # 19 | 20 | # for tests 21 | if [ -n "${SSHGATE_CONFIGURATION}" ]; then 22 | . "${SSHGATE_CONFIGURATION}" 23 | fi 24 | 25 | if [ -z "${SSHGATE_DIRECTORY:-}" ]; then 26 | if [ -r /etc/sshgate.conf ]; then 27 | . /etc/sshgate.conf 28 | else 29 | echo "ERROR: can't load sshGate configuration file" 30 | fi 31 | fi 32 | 33 | if [ "${__SSHGATE_SETUP__:-}" != 'Loaded' ]; then 34 | __SSHGATE_SETUP__='Loaded' 35 | 36 | # remove trailing / 37 | SSHGATE_DIRECTORY="${SSHGATE_DIRECTORY%%/}" 38 | 39 | SET_GLOBAL () { 40 | local value= 41 | value=$( eval echo "\${${1}}" ) 42 | [ -z "${value}" ] && eval "$1=\"$2\"" 43 | } 44 | 45 | # directories of sshgates 46 | SET_GLOBAL SSHGATE_DIR_DATA "${SSHGATE_DIRECTORY}/data" 47 | SET_GLOBAL SSHGATE_DIR_TEMPLATES "${SSHGATE_DIR_DATA}/templates" 48 | SET_GLOBAL SSHGATE_DIR_BIN "${SSHGATE_DIRECTORY}/bin" 49 | SET_GLOBAL SSHGATE_DIR_CORE "${SSHGATE_DIR_BIN}/core" 50 | SET_GLOBAL SSHGATE_DIR_TEST "${SSHGATE_DIR_BIN}/tests" 51 | SET_GLOBAL SSHGATE_DIR_USERS "${SSHGATE_DIRECTORY}/users" 52 | SET_GLOBAL SSHGATE_DIR_TARGETS "${SSHGATE_DIRECTORY}/targets" 53 | SET_GLOBAL SSHGATE_DIR_USERS_GROUPS "${SSHGATE_DIRECTORY}/users.groups" 54 | SET_GLOBAL SSHGATE_DIR_LOGS "${SSHGATE_DIRECTORY}/logs" 55 | SET_GLOBAL SSHGATE_DIR_LOGS_TARGETS "${SSHGATE_DIR_LOGS}/targets-logs" 56 | SET_GLOBAL SSHGATE_DIR_LOGS_USERS "${SSHGATE_DIR_LOGS}/users-logs" 57 | SET_GLOBAL SSHGATE_DIR_ARCHIVE "${SSHGATE_DIRECTORY}/archives" 58 | 59 | SET_GLOBAL SSHGATE_EDITOR "${SSHGATE_EDITOR:-${EDITOR}}" 60 | 61 | SSHGATE_TARGET_PRIVATE_SSHKEY_FILENAME='sshkey.priv' 62 | SSHGATE_TARGET_PUBLIC_SSHKEY_FILENAME='sshkey.pub' 63 | 64 | SET_GLOBAL SSHGATE_TARGET_DEFAULT_PRIVATE_SSHKEY_FILE \ 65 | "${SSHGATE_DIR_DATA}/${SSHGATE_TARGET_PRIVATE_SSHKEY_FILENAME}" 66 | SET_GLOBAL SSHGATE_TARGET_DEFAULT_PUBLIC_SSHKEY_FILE \ 67 | "${SSHGATE_DIR_DATA}/${SSHGATE_TARGET_PUBLIC_SSHKEY_FILENAME}" 68 | 69 | SSHGATE_TARGETS_USER_ACCESS_FILENAME='access.users' 70 | SSHGATE_TARGETS_USERGROUP_ACCESS_FILENAME='access.groups' 71 | SSHGATE_TARGETS_SSH_CONFIG_FILENAME='ssh_conf' 72 | SSHGATE_TARGETS_SSH_LOGINS_FILENAME='ssh_logins.list' 73 | 74 | # logs files 75 | SET_GLOBAL SSHGATE_LOGS_CURRENT_SESSION_FILE "${SSHGATE_DIR_LOGS}/current_session.log" 76 | SET_GLOBAL SSHGATE_GLOBAL_SESSION_LOG_FILE "${SSHGATE_DIR_LOGS}/sessions.log" 77 | 78 | SET_GLOBAL SSHGATE_TOS_FILENAME "TOS.txt" 79 | 80 | fi # __SSHGATE_SETUP__ 81 | -------------------------------------------------------------------------------- /tests/user.testcase: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright (c) 2010 Linagora 3 | # Patrick Guiran 4 | # http://github.com/Tauop/ScriptHelper 5 | # 6 | # ScriptHelper is free software, you can redistribute it and/or modify 7 | # it under the terms of the GNU General Public License as 8 | # published by the Free Software Foundation; either version 2 of 9 | # the License, or (at your option) any later version. 10 | # 11 | # ScriptHelper is distributed in the hope that it will be useful, 12 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | # GNU General Public License for more details. 15 | # 16 | # You should have received a copy of the GNU Lesser General Public License 17 | # along with this program. If not, see . 18 | # 19 | # -------------------------------------------------------------------------- 20 | 21 | mDOTHIS 'Generate user tests' 22 | 23 | cat >"${expected_test_file}" < user list 25 | 26 | sshGate > user add pguiran mail pguiran@linagora.com 27 | $(cat "${sshkey_pub_test_file}" | while read line ; do echo "<<-${line}"; done; echo "->>" ) 28 | sshGate > user list 29 | pguiran 30 | sshGate > user list *gui* 31 | pguiran 32 | sshGate > user add scourtois mail simon@courtois.fr 33 | $(echo "<<-lol"; echo "<<-rolf"; echo "->>" ) 34 | sshGate > user scourtois display sshkey 35 | # public sshkey scourtois 36 | lol 37 | rolf 38 | sshGate > user scourtois edit sshkey 39 | $(cat "${sshkey_pub_test_file}" | while read line ; do echo "<<-${line}"; done; echo "->>" ) 40 | sshGate > user scourtois update auth_keys 41 | sshGate > user list sco* 42 | scourtois 43 | sshGate > user pguiran display conf 44 | MAIL="pguiran@linagora.com" 45 | sshGate > user scourtois 46 | sshGate [user scourtois]> set conf MAIL scourtois@linagora.com 47 | sshGate [user scourtois]> set conf IS_ADMIN true 48 | sshGate [user scourtois]> display conf 49 | MAIL="scourtois@linagora.com" 50 | IS_ADMIN="true" 51 | sshGate [user scourtois]> set conf IS_ADMIN 52 | sshGate [user scourtois]> display conf 53 | MAIL="scourtois@linagora.com" 54 | sshGate [user scourtois]> set conf IS_ADMIN false 55 | sshGate [user scourtois]> display conf 56 | MAIL="scourtois@linagora.com" 57 | IS_ADMIN="false" 58 | sshGate [user scourtois]> del conf IS_ADMIN 59 | sshGate [user scourtois]> display conf 60 | MAIL="scourtois@linagora.com" 61 | sshGate [user scourtois]> quit 62 | sshGate > user del scourtois 63 | sshGate > user list 64 | pguiran 65 | sshGate > user build auth_keys 66 | sshGate > exit 67 | EOF 68 | 69 | grep -E '^(<<=|<<-|->>|sshGate [^>]*>)' < "${expected_test_file}" \ 70 | | sed -e 's/^sshGate [^>]*> //; s/^<<=//;' > "${input_test_file}" 71 | 72 | tmp_file="${expected_test_file}.$(RANDOM)" 73 | grep -v -E '^(<<=|<<-|->>)' < "${expected_test_file}" > "${tmp_file}" 74 | mv "${tmp_file}" "${expected_test_file}" 75 | 76 | mOK 77 | 78 | # -------------------------------------------------------------------------- 79 | mDOTHIS 'Launch user tests' 80 | ASK_SET_AUTOANSWER_FILE "${input_test_file}" 81 | ( CLI_RUN > "${output_test_file}" ) 82 | result_diff=$( diff -au "${expected_test_file}" "${output_test_file}" ) 83 | if [ $? -eq 0 ]; then 84 | mOK 85 | else 86 | echo "Test Failed" 87 | echo "==========================================================" 88 | echo "${result_diff}" 89 | echo "==========================================================" 90 | fi 91 | -------------------------------------------------------------------------------- /bin/core/help.func: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright (c) 2010 Linagora 3 | # Patrick Guiran 4 | # http://github.com/Tauop/sshGate 5 | # 6 | # sshGate is free software, you can redistribute it and/or modify 7 | # it under the terms of the GNU General Public License as 8 | # published by the Free Software Foundation; either version 2 of 9 | # the License, or (at your option) any later version. 10 | # 11 | # sshGate is distributed in the hope that it will be useful, 12 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | # GNU General Public License for more details. 15 | # 16 | # You should have received a copy of the GNU Lesser General Public License 17 | # along with this program. If not, see . 18 | # 19 | # README --------------------------------------------------------------------- 20 | # 21 | # Collection of all sshgate's help related functions 22 | # 23 | # ---------------------------------------------------------------------------- 24 | 25 | if [ "${__SSHGATE_CORE__}" != 'Loaded' ]; then 26 | echo "ERROR: Only sshgate.core can load user.func."; exit 1; 27 | fi 28 | 29 | if [ "${__HELP_FUNC__:-}" != 'Loaded' ]; then 30 | __HELP_FUNC__='Loaded' 31 | 32 | SSHGATE_GET_HELP() { 33 | local type="$1" cli_command="$2" func= help= help_menu= sed_code= 34 | if [ "${type}" = 'command' ]; then 35 | help="$4" 36 | if [ -z "${help}" ]; then 37 | func="${3%% *}" 38 | sed_code="${sed_code} /usage: ${func} / { :next n; s/^ *# *desc: *\(.*\) *$/\1/p; t; b next; };" 39 | sed_code="${sed_code} /usage: ${func}\$/ { :next n; s/^ *# *desc: *\(.*\) *$/\1/p; t; b next; };" 40 | help=$( find "${SSHGATE_DIR_CORE}/" -type f -exec cat {} \; | sed -n -e "${sed_code}" ) 41 | fi 42 | printf "%s\t%s\t%s" "${type}" "${cli_command}" "${help}" 43 | else 44 | help="$3" 45 | if [ -n "${help}" ]; then 46 | cli_command=$( private_PURIFY_CLI_COMMAND "${cli_command}" ) 47 | help_menu=$( echo "${cli_command}" | sed -e 's/?//g;s/ */ /g;' ) 48 | printf "%s\t%s\t%s\t%s" "${type}" "${help_menu}" "${cli_command}" "${help}" 49 | fi 50 | fi 51 | 52 | return 0; 53 | } 54 | 55 | SSHGATE_DISPLAY_HELP() { 56 | local line= cmd= help= 57 | grep $'^menu\t' < "${__CLI_HELP_FILE__}" \ 58 | | cut -d $'\t' -f 2,4 | tr $'\t' ':' \ 59 | | ( while read line ; do 60 | cmd="${line%:*}" 61 | help="${line#${cmd}:}" 62 | printf " %-20s\t-- %s\n" "${cmd}" "${help}" 63 | done; 64 | printf " %-20s\t-- %s \n" "all" "Display all commands" 65 | ) | sort -u 66 | return 0 67 | } 68 | 69 | SSHGATE_DISPLAY_HELP_FOR() { 70 | local cli_cmd= line= cmd= help= 71 | 72 | cli_cmd=$( grep $'^menu\t' < "${__CLI_HELP_FILE__}" \ 73 | | cut -d $'\t' -f 2,3 | tr $'\t' ':' \ 74 | | grep "^$*:" | head -n 1 | cut -d ':' -f2 ) 75 | cli_cmd=$( echo "${cli_cmd}[: ]" | sed -e 's/?/[^ ]*/g') 76 | 77 | grep $'^command' < "${__CLI_HELP_FILE__}" \ 78 | | cut -d $'\t' -f 2- | tr $'\t' ':' \ 79 | | grep "^${cli_cmd}" \ 80 | | while read line ; do 81 | [ -z "${line}" ] && continue; 82 | cmd="${line%:*}" 83 | help="${line#"${cmd}":}" 84 | printf " %-20s\t-- %s\n" "${cmd}" "${help}" 85 | done 86 | return 0 87 | } 88 | 89 | fi # if [ "${__HELP_FUNC__}" != 'Loaded' ]; then 90 | -------------------------------------------------------------------------------- /README: -------------------------------------------------------------------------------- 1 | == Welcome to sshGate server == 2 | 3 | sshGate is a tool which helps to configure an OpenSSH server in order to have 4 | a SSH proxy. sshGate uses the double SSH method to be able to connect to 5 | a target host. In fact, sshGate has private ssh-keys of target hosts, makes 6 | ACL checks and can log what users do on a given target host. 7 | 8 | /-------> target host N 9 | /--------> . . . 10 | user ----> sshGate ----> target host 1 11 | |-> ACL 12 | |-> targets private sshkeys 13 | |-> users public sshkeys 14 | 15 | sshGate is under GPLv2 license. 16 | 17 | Server project is located at http://github.com/Tauop/sshGate 18 | Client project is located at http://github.com/Tauop/sshGate-client 19 | ScriptHelper project is located at http://github.com/Tauop/ScriptHelper 20 | 21 | 22 | == Install & Upgrade == 23 | 24 | If you crab the source for github.com, you need to build a sshGate-server tarball. 25 | For more information : https://github.com/Tauop/sshGate/wiki/BuildPackages 26 | 27 | Just run the ./install.sh script and answer to questions. 28 | It you make a upgrade, the installed configuration can be re-used, and 29 | data migration can be performed. 30 | 31 | For more information : https://github.com/Tauop/sshGate/wiki/ServerInstallation 32 | 33 | == Documentation == 34 | 35 | The project documentation is available on the github wiki at http://github.com/Tauop/sshGate/wiki 36 | 37 | 38 | == Configuration == 39 | 40 | After installation, sshGate configuration can be changed through the sshgate-configure script, 41 | or you can change settings values in the /etc/sshgate.conf files. This configuration file sets 42 | main settings, and can override internal settings too. 43 | 44 | Main settings : 45 | - SSHGATE_VERSION : version of sshGate (do not edit) 46 | - SSHGATE_BUILD : the build number of sshGate (internal use - do not edit) 47 | - SSHGATE_DIRECTORY : root directory of sshGate program 48 | - SCRIPT_HELPER_DIRECTORY : ScriptHelper dependance directory 49 | - SSHGATE_GATE_ACCOUNT : the unix account used by sshGate 50 | - SSHGATE_ALLOW_REMOTE_COMMAND : Do we allow remote command like "sshg 'cmd list targets'" ? default: Y 51 | - SSHGATE_USE_REMOTE_ADMIN_CLI : Do we allow remote administration CLI ? default: Y 52 | - SSHGATE_USERS_MUST_ACCEPT_TOS : Do users have to accept TOS at the first connection ? default: Y 53 | - SSHGATE_EDITOR : editor program to use by sshGate. default: ${EDITOR} 54 | - SSHGATE_TARGETS_SCP_PATH : default SCP path when it's not specified. default: ~/ 55 | - SSHGATE_TARGET_DEFAULT_SSH_LOGIN : default ssh login to use when connecting to target host. default: root 56 | - SSHGATE_DEFAULT_LANGUAGE : The default language of sshGate users 57 | - SSHGATE_MAIL_SEND : Is sshGate mail notification activated ? default: N 58 | - SSHGATE_MAIL_TO : mail to this mail adresse if [SSHGATE_MAIL_SEND] is 'Y' 59 | - SSHGATE_MAIL_SUBJECT : E-mail subject to use 60 | 61 | other settings which can be override in /etc/sshgate.conf 62 | - SSHGATE_DIR_DATA : sshGate data root directory 63 | - SSHGATE_DIR_TEMPLATES : Directory containing multi-language templates 64 | - SSHGATE_DIR_BIN : binaries of sshGate. default = [SSHGATE_DIRECTORY]/bin 65 | - SSHGATE_DIR_CORE : all sshGate 'func' and 'core' files (internal sshGate library) 66 | - SSHGATE_DIR_TEST : sshGate test files 67 | - SSHGATE_DIR_USERS : users data (ssh keys and properties) 68 | - SSHGATE_DIR_TARGETS : targets data (ssh keys, properties, access, logins, ...) 69 | - SSHGATE_DIR_USERS_GROUPS : usergroups data 70 | - SSHGATE_DIR_LOGS : logs root directory 71 | - SSHGATE_DIR_LOGS_TARGETS : targets logs directory 72 | - SSHGATE_DIR_LOGS_USERS : users logs directory 73 | - SSHGATE_DIR_ARCHIVE : logs archives directory 74 | - SSHGATE_TARGET_PRIVATE_SSHKEY_FILENAME : filename of the target private ssh key 75 | - SSHGATE_TARGET_PUBLIC_SSHKEY_FILENAME : filename of the target public ssh key 76 | - SSHGATE_TARGET_DEFAULT_PRIVATE_SSHKEY_FILE : path to the default target private ssh key file 77 | - SSHGATE_TARGET_DEFAULT_PUBLIC_SSHKEY_FILE : path to the default target public ssh key file 78 | - SSHGATE_TARGETS_USER_ACCESS_FILENAME : name of the target users access file 79 | - SSHGATE_TARGETS_USERGROUP_ACCESS_FILENAME : name of the target usergroup access file 80 | - SSHGATE_TARGETS_SSH_CONFIG_FILENAME : name of the target ssh configuration file 81 | - SSHGATE_TARGETS_SSH_LOGINS_FILENAME : name of the target ssh login list file 82 | - SSHGATE_LOGS_CURRENT_SESSION_FILE : path to the current session log file 83 | - SSHGATE_TOS_FILENAME : name of the file containing TOS 84 | -------------------------------------------------------------------------------- /tests/access.testcase: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright (c) 2010 Linagora 3 | # Patrick Guiran 4 | # http://github.com/Tauop/ScriptHelper 5 | # 6 | # ScriptHelper is free software, you can redistribute it and/or modify 7 | # it under the terms of the GNU General Public License as 8 | # published by the Free Software Foundation; either version 2 of 9 | # the License, or (at your option) any later version. 10 | # 11 | # ScriptHelper is distributed in the hope that it will be useful, 12 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | # GNU General Public License for more details. 15 | # 16 | # You should have received a copy of the GNU Lesser General Public License 17 | # along with this program. If not, see . 18 | # 19 | # -------------------------------------------------------------------------- 20 | 21 | mDOTHIS 'Generate access tests' 22 | 23 | hostname=$( hostname | tr '[:upper:]' '[:lower:]' ) 24 | alias="${hostname}2" 25 | ip=$( hostname -i ) 26 | 27 | cat >"${expected_test_file}" < target add ${hostname} 29 | Use the sshGate default sshkey for this target host [Y] ? Y 30 | <<=Y 31 | sshGate > target add ${ip} 32 | Use the sshGate default sshkey for this target host [Y] ? N 33 | <<=N 34 | $(cat "${sshkey_priv_test_file}" | while read line ; do echo "<<-${line}"; done; echo "->>" ) 35 | sshGate > target ${hostname} add alias ${alias} 36 | sshGate > target ${hostname} ssh add login root 37 | sshGate > target ${ip} ssh add login tauop 38 | sshGate > user add pguiran mail pguiran@linagora.com 39 | $(cat "${sshkey_pub_test_file}" | while read line ; do echo "<<-${line}"; done; echo "->>" ) 40 | sshGate > user add scourtois mail simon@courtois.fr 41 | $(cat "${sshkey_pub_test_file}" | while read line ; do echo "<<-${line}"; done; echo "->>" ) 42 | sshGate > usergroup add LRS 43 | sshGate > usergroup add OSSA 44 | sshGate > usergroup LRS add user pguiran 45 | sshGate > usergroup LRS add user scourtois 46 | sshGate > usergroup OSSA add user pguiran 47 | sshGate > target ${hostname} access add user pguiran 48 | sshGate > target ${hostname} access add user scourtois 49 | sshGate > target root@${hostname} access add user scourtois 50 | sshGate > target ${hostname} access add usergroup LRS 51 | sshGate > target root@${hostname} access add usergroup OSSA 52 | sshGate > target ${ip} access add user scourtois 53 | sshGate > target tauop@${ip} access add usergroup OSSA 54 | sshGate > target ${hostname} access list users 55 | pguiran 56 | scourtois 57 | sshGate > target root@${hostname} access list users 58 | pguiran 59 | scourtois 60 | sshGate > target ${alias} access list users 61 | pguiran 62 | scourtois 63 | sshGate > target ${ip} access list users 64 | scourtois 65 | sshGate > target tauop@${ip} access list users 66 | pguiran 67 | sshGate > target ${hostname} access list usergroups 68 | LRS 69 | sshGate > target root@${hostname} access list usergroups 70 | OSSA 71 | sshGate > target root@${hostname} access list usergroups 72 | OSSA 73 | sshGate > target tauop@${ip} access list usergroups 74 | OSSA 75 | sshGate > target ${hostname} access info 76 | scourtois ---> root@${hostname} 77 | pguiran,scourtois ---> ${user_unix_test_account}@${hostname} 78 | pguiran --- usergroup(OSSA) ---> root@${hostname} 79 | pguiran,scourtois --- usergroup(LRS) ---> ${user_unix_test_account}@${hostname} 80 | sshGate > user pguiran access info 81 | pguiran ---> ${user_unix_test_account}@${hostname} 82 | pguiran --- usergroup(LRS) ---> ${user_unix_test_account}@${hostname} 83 | pguiran --- usergroup(OSSA) ---> tauop@${ip} 84 | pguiran --- usergroup(OSSA) ---> root@${hostname} 85 | sshGate > usergroup LRS access info 86 | pguiran,scourtois --- usergroup(LRS) ---> ${user_unix_test_account}@${hostname} 87 | sshGate > usergroup OSSA access info 88 | pguiran --- usergroup(OSSA) ---> root@${hostname},tauop@${ip} 89 | sshGate > usergroup LRS list targets 90 | ${user_unix_test_account}@${hostname} 91 | sshGate > usergroup OSSA list targets 92 | root@${hostname} 93 | tauop@${ip} 94 | sshGate > user pguiran has access ${user_unix_test_account}@${hostname} 95 | true 96 | sshGate > user scourtois has access root@${hostname} 97 | true 98 | sshGate > target root@${hostname} access del usergroup OSSA 99 | sshGate > target ${ip} access del user scourtois 100 | sshGate > target ${hostname} access info 101 | scourtois ---> root@${hostname} 102 | pguiran,scourtois ---> ${user_unix_test_account}@${hostname} 103 | pguiran,scourtois --- usergroup(LRS) ---> ${user_unix_test_account}@${hostname} 104 | sshGate > user scourtois list targets 105 | root@${hostname} 106 | ${user_unix_test_account}@${hostname} 107 | sshGate > target ${ip} access list users 108 | sshGate > usergroup del LRS 109 | sshGate > target ${hostname} access info 110 | scourtois ---> root@${hostname} 111 | pguiran,scourtois ---> ${user_unix_test_account}@${hostname} 112 | sshGate > user del scourtois 113 | sshGate > target ${hostname} access info 114 | pguiran ---> ${user_unix_test_account}@${hostname} 115 | sshGate > exit 116 | EOF 117 | 118 | grep -E '^(<<=|<<-|->>|sshGate [^>]*>)' < "${expected_test_file}" \ 119 | | sed -e 's/^sshGate [^>]*> //; s/^<<=//;' > "${input_test_file}" 120 | 121 | tmp_file="${expected_test_file}.$(RANDOM)" 122 | grep -v -E '^(<<=|<<-|->>)' < "${expected_test_file}" > "${tmp_file}" 123 | mv "${tmp_file}" "${expected_test_file}" 124 | 125 | mOK 126 | 127 | # -------------------------------------------------------------------------- 128 | mDOTHIS 'Launch access tests' 129 | ASK_SET_AUTOANSWER_FILE "${input_test_file}" 130 | ( CLI_RUN > "${output_test_file}" 4 | # http://github.com/Tauop/sshGate 5 | # 6 | # sshGate is free software, you can redistribute it and/or modify 7 | # it under the terms of the GNU General Public License as 8 | # published by the Free Software Foundation; either version 2 of 9 | # the License, or (at your option) any later version. 10 | # 11 | # sshGate is distributed in the hope that it will be useful, 12 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | # GNU General Public License for more details. 15 | # 16 | # You should have received a copy of the GNU Lesser General Public License 17 | # along with this program. If not, see . 18 | # 19 | # README --------------------------------------------------------------------- 20 | # 21 | # Collection of misc functions 22 | # 23 | # ---------------------------------------------------------------------------- 24 | 25 | if [ "${__SSHGATE_CORE__}" != 'Loaded' ]; then 26 | echo "ERROR: Only sshgate.core can load user.func."; exit 1; 27 | fi 28 | 29 | if [ "${__TARGET_KNOWN_HOSTS_FUNC__:-}" != 'Loaded' ]; then 30 | __TARGET_KNOWN_HOSTS_FUNC__='Loaded' 31 | 32 | # usage: private_TARGET_KNOWN_HOSTS_ADD [ ] 33 | # desc: force re-write of sshgate account ~/.ssh/authorized_keys2 file 34 | # note: if is not specified, determine it with SSHGATE_ACCOUNT_HOMEDIR 35 | private_TARGET_KNOWN_HOSTS_ADD () { 36 | local target= target_port= target_real= target_ssh_config= file= proxy= 37 | 38 | if [ $# -ne 1 -a $# -ne 2 ]; then 39 | BAD_ARGUMENTS ; return 1; 40 | fi 41 | 42 | target_real=$( TARGET_REAL "$1" ) 43 | if [ -z "${target_real}" ]; then 44 | ERROR "Target host '${target}' doesn't exist"; return 1; 45 | fi 46 | 47 | [ $# -eq 2 ] && file="$2" 48 | [ -z "${file}" ] && file="$(SSHGATE_ACCOUNT_HOMEDIR)/.ssh/known_hosts" 49 | [ ! -f "${file}" ] && touch "${file}" 50 | 51 | target_ssh_config="${SSHGATE_DIR_TARGETS}/${target_real}/${SSHGATE_TARGETS_SSH_CONFIG_FILENAME}.$( GET_LOGIN "${target}" )" 52 | if [ -r "${target_ssh_config}" ]; then 53 | target_port=$( < "${target_ssh_config}" grep 'Port' | sed -e 's/^[^0-9]*\([0-9]*\)[^0-9]*$/\1/' ) 54 | fi 55 | target_port="${target_port:-22}" 56 | 57 | proxy=$( TARGET_GET_CONF "${target_real}" SSH_PROXY ) 58 | if [ -z "${proxy}" ]; then 59 | ssh-keyscan -H -p "${target_port}" -t dsa,rsa "${target_real}" 2>/dev/null >> "${file}" 60 | [ $? -ne 0 ] && return 1 61 | else 62 | TARGET_SSH_RUN_COMMAND "${proxy}" \ 63 | "ssh-keyscan -H -p ${target_port} -t dsa,rsa '${target_real}' 2>/dev/null;" >> "${file}" 64 | [ $? -ne 0 ] && return 1 65 | fi 66 | 67 | chown "${SSHGATE_GATE_ACCOUNT}" "${file}" 68 | return 0; 69 | } 70 | 71 | # usage: private_TARGET_KNOWN_HOSTS_DEL [ ] 72 | # desc: delete the public host sshkey of the from the known_hosts file 73 | # note: if is not specified, determine it with SSHGATE_ACCOUNT_HOMEDIR 74 | private_TARGET_KNOWN_HOSTS_DEL() { 75 | local target= target_real= target_login= file= target_ssh_config= target_port= proxy= 76 | if [ $# -eq 0 -o $# -gt 2 ]; then 77 | BAD_ARGUMENTS ; return 1; 78 | fi 79 | 80 | target="$1" 81 | [ $# -eq 2 ] && file="$2" 82 | 83 | target_login=$( GET_LOGIN "${target}" ) 84 | target_real=$( TARGET_REAL "${target}" ) 85 | if [ -z "${target_real}" ]; then 86 | ERROR "Target host '${target}' doesn't exist"; return 1; 87 | fi 88 | 89 | [ -z "${file}" ] && file="$(SSHGATE_ACCOUNT_HOMEDIR)/.ssh/known_hosts" 90 | [ ! -f "${file}" ] && return 0; 91 | 92 | target_ssh_config="${SSHGATE_DIR_TARGETS}/${target_real}/${SSHGATE_TARGETS_SSH_CONFIG_FILENAME}.${target_login}" 93 | if [ -r "${target_ssh_config}" ]; then 94 | target_port=$( < "${target_ssh_config}" grep 'Port' | sed -e 's/^[^0-9]*\([0-9]*\)[^0-9]*$/\1/' ) 95 | fi 96 | target_port="${target_port:-22}" 97 | 98 | proxy=$( TARGET_GET_CONF "${target_real}" SSH_PROXY ) 99 | if [ -z "${proxy}" ]; then 100 | ssh-keygen -R "${target_real}" -f "${file}" 2>/dev/null 101 | [ $? -ne 0 ] && return 1 102 | rm -f "${file}.old" 2>/dev/null 103 | [ -e "${file}" ] && chown "${SSHGATE_GATE_ACCOUNT}" "${file}" 104 | else 105 | TARGET_SSH_RUN_COMMAND "${proxy}" \ 106 | "ssh-keyscan -R '${target_real}' -f '${file}' 2>/dev/null; 107 | rm -f '${file}.old' 2>/dev/null; 108 | [ -e '${file}' ] && chown '${SSHGATE_GATE_ACCOUNT}' '${file}'" 109 | [ $? -ne 0 ] && return 1 110 | fi 111 | return 0; 112 | } 113 | 114 | # usage: private_TARGET_SSH_BUILD_KNOWN_HOSTS 115 | # desc: force re-write of sshgate account ~/.ssh/known_hosts file 116 | # important: need to be root 117 | private_TARGET_SSH_BUILD_KNOWN_HOSTS () { 118 | local home_dir= target= alias= 119 | home_dir=$( SSHGATE_ACCOUNT_HOMEDIR ) 120 | if [ -z "${home_dir}" ]; then 121 | ERROR "Can't find home directory of ${SSHGATE_GATE_ACCOUNT} user" 122 | return 1; 123 | fi 124 | 125 | echo -n '' > "${home_dir}/.ssh/known_hosts" 126 | for target in $( TARGETS_LIST ); do 127 | target=$( GET_HOST "${target}" ) 128 | echo -n "- ${target} ... " 129 | private_TARGET_KNOWN_HOSTS_ADD "${target}" "${home_dir}/.ssh/known_hosts" 130 | if [ $? -ne 0 ]; then 131 | # don't try for ip and alias if we failed here 132 | echo 'KO' 133 | continue 134 | fi 135 | echo 'OK' 136 | done 137 | 138 | return 0; 139 | } 140 | 141 | # usage: TARGET_SSH_UPDATE_KNOWN_HOSTS [] 142 | # desc: update known_hosts file entry for all hosts or 143 | TARGET_SSH_UPDATE_KNOWN_HOSTS () { 144 | if [ $# -gt 1 ]; then 145 | BAD_ARGUMENTS ; return 1; 146 | fi 147 | 148 | if [ $# -eq 1 ]; then 149 | private_TARGET_KNOWN_HOSTS_DEL "$1" \ 150 | && private_TARGET_KNOWN_HOSTS_ADD "$1" \ 151 | && return 0; 152 | else 153 | private_TARGET_SSH_BUILD_KNOWN_HOSTS "$1" && return 0 154 | fi 155 | 156 | return 1; # error 157 | } 158 | 159 | fi # end of: if [ "${__TARGET_KNOWN_HOSTS_FUNC__:-}" != 'Loaded' ]; then 160 | -------------------------------------------------------------------------------- /bin/core/usergroup.func: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright (c) 2010 Linagora 3 | # Patrick Guiran 4 | # http://github.com/Tauop/sshGate 5 | # 6 | # sshGate is free software, you can redistribute it and/or modify 7 | # it under the terms of the GNU General Public License as 8 | # published by the Free Software Foundation; either version 2 of 9 | # the License, or (at your option) any later version. 10 | # 11 | # sshGate is distributed in the hope that it will be useful, 12 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | # GNU General Public License for more details. 15 | # 16 | # You should have received a copy of the GNU Lesser General Public License 17 | # along with this program. If not, see . 18 | # 19 | # README --------------------------------------------------------------------- 20 | # 21 | # Collection of all users' group related functions 22 | # 23 | # ---------------------------------------------------------------------------- 24 | 25 | if [ "${__SSHGATE_CORE__}" != 'Loaded' ]; then 26 | echo "ERROR: Only sshgate.core can load user.func."; exit 1; 27 | fi 28 | 29 | if [ "${__USERGROUP_FUNC__:-}" != 'Loaded' ]; then 30 | __USERGROUP_FUNC__='Loaded' 31 | 32 | # usage: USERGROUPS_LIST 33 | # desc: List all users groups 34 | # note: users' group name are separated by '\n' 35 | USERGROUPS_LIST () { 36 | local res= find_opt= 37 | [ $# -eq 1 ] && find_opt="-iname '$1'" 38 | res=$( eval "find '${SSHGATE_DIR_USERS_GROUPS}' -mindepth 1 -type f ${find_opt} -printf '%P\n'" ) 39 | echo "${res}" | sort -u 40 | return 0; 41 | } 42 | 43 | # usage: USERGROUP_ADD 44 | # desc: Create a users group 45 | USERGROUP_ADD () { 46 | local usergroup= 47 | 48 | if [ $# -ne 1 ]; then 49 | BAD_ARGUMENTS ; return 1; 50 | fi 51 | 52 | usergroup="$1" 53 | if [ -z "${usergroup}" ]; then 54 | BAD_ARGUMENTS ; return 1; 55 | fi 56 | if [ -f "${SSHGATE_DIR_USERS_GROUPS}/${usergroup}" ]; then 57 | ERROR "User group '${usergroup}' already exists" ; return 1 58 | fi 59 | 60 | touch "${SSHGATE_DIR_USERS_GROUPS}/${usergroup}" 61 | private_MAIL_APPEND "User Group ${usergroup} added" 62 | 63 | return 0; 64 | } 65 | 66 | # usage: USERGROUP_DEL 67 | # desc: Delete a users group 68 | USERGROUP_DEL () { 69 | local usergroup= 70 | if [ $# -ne 1 ]; then 71 | BAD_ARGUMENTS ; return 1; 72 | fi 73 | 74 | usergroup="$1" 75 | if [ ! -f "${SSHGATE_DIR_USERS_GROUPS}/${usergroup}" -o -z "${usergroup}" ]; then 76 | ERROR "User group '${usergroup}' doesn't exist" ; return 1 77 | fi 78 | 79 | for target in $( USERGROUP_LIST_TARGETS "${usergroup}" ); do 80 | TARGET_ACCESS_DEL_USERGROUP "${target}" "${usergroup}" 81 | done 82 | 83 | rm -f "${SSHGATE_DIR_USERS_GROUPS}/${usergroup}" 84 | private_MAIL_APPEND "User Group ${usergroup} removed" 85 | 86 | return 0 87 | } 88 | 89 | # usage: USERGROUP_LIST_USERS 90 | # desc: List users of a group 91 | # note: user names are separated by \n 92 | USERGROUP_LIST_USERS () { 93 | local usergroup= 94 | if [ $# -ne 1 ]; then 95 | BAD_ARGUMENTS ; return 1; 96 | fi 97 | 98 | usergroup="$1" 99 | if [ ! -f "${SSHGATE_DIR_USERS_GROUPS}/${usergroup}" -o -z "${usergroup}" ]; then 100 | ERROR "User group '${usergroup}' doesn't exist" ; return 1; 101 | fi 102 | 103 | cat "${SSHGATE_DIR_USERS_GROUPS}/${usergroup}" | sort -u 104 | return 0; 105 | } 106 | 107 | # usage: USERGROUP_ADD_USER 108 | # desc: Add an user into a group 109 | USERGROUP_ADD_USER () { 110 | local usergroup= user= 111 | if [ $# -ne 2 ]; then 112 | BAD_ARGUMENTS ; return 1; 113 | fi 114 | 115 | usergroup="$1"; user="$2"; 116 | if [ ! -f "${SSHGATE_DIR_USERS_GROUPS}/${usergroup}" -o -z "${usergroup}" ]; then 117 | ERROR "User group '${usergroup}' doesn't exist" ; return 1; 118 | fi 119 | if [ ! -f "${SSHGATE_DIR_USERS}/${user}" -o -z "${user}" ]; then 120 | ERROR "User '${user}' doesn't exist" ; return 1; 121 | fi 122 | 123 | private_ACL_FILE_ADD "${user}" "${SSHGATE_DIR_USERS_GROUPS}/${usergroup}" 124 | private_MAIL_APPEND "User ${user} added to User Group ${usergroup}" 125 | 126 | return 0; 127 | } 128 | 129 | # usage: USERGROUP_DEL_USER 130 | # desc: Remove an user from a group 131 | USERGROUP_DEL_USER () { 132 | local usergroup= user= 133 | if [ $# -ne 2 ]; then 134 | BAD_ARGUMENTS ; return 1; 135 | fi 136 | 137 | usergroup="$1"; user="$2" 138 | if [ ! -f "${SSHGATE_DIR_USERS_GROUPS}/${usergroup}" -o -z "${usergroup}" ]; then 139 | ERROR "User group '${usergroup}' doesn't exist" ; return 1; 140 | fi 141 | if [ ! -f "${SSHGATE_DIR_USERS}/${user}" -o -z "${user}" ]; then 142 | ERROR "User '${user}' doesn't exist" ; return 1; 143 | fi 144 | 145 | private_ACL_FILE_DEL "${user}" "${SSHGATE_DIR_USERS_GROUPS}/${usergroup}" 146 | private_MAIL_APPEND "User ${user} removed from User Group ${usergroup}" 147 | 148 | return 0; 149 | } 150 | 151 | # usage: USERGROUP_LIST_TARGETS 152 | # desc: List targets which usergroup has access to 153 | USERGROUP_LIST_TARGETS () { 154 | local usergroup= target= 155 | if [ $# -ne 1 ]; then 156 | BAD_ARGUMENTS ; return 1; 157 | fi 158 | 159 | usergroup="$1" 160 | if [ ! -f "${SSHGATE_DIR_USERS_GROUPS}/${usergroup}" -o -z "${usergroup}" ]; then 161 | ERROR "User group '${usergroup}' doesn't exist" ; return 1; 162 | fi 163 | 164 | for target in $( find "${SSHGATE_DIR_TARGETS}" \ 165 | -name "${SSHGATE_TARGETS_USERGROUP_ACCESS_FILENAME}*" \ 166 | -exec grep -l "^${usergroup}\$" {} \; | sort -u ); do 167 | target=$( echo "${target}" | sed -e "s|^.*/\([^/]*\)/${SSHGATE_TARGETS_USERGROUP_ACCESS_FILENAME}.\(.*\)$|\2@\1|" ) 168 | echo "${target}" 169 | done | sort -u 170 | return 0; 171 | } 172 | 173 | # usage: USERGROUP_ACCESS_INFO 174 | # desc: List all target whose users of the group have access to 175 | USERGROUP_ACCESS_INFO () { 176 | local usergroup= users= targets= 177 | if [ $# -ne 1 ]; then 178 | BAD_ARGUMENTS ; return 1; 179 | fi 180 | 181 | usergroup="$1" 182 | if [ ! -f "${SSHGATE_DIR_USERS_GROUPS}/${usergroup}" -o -z "${usergroup}" ]; then 183 | ERROR "User group '${usergroup}' doesn't exist" ; return 1; 184 | fi 185 | 186 | users=$( USERGROUP_LIST_USERS "${usergroup}" ); users=$( echo -n "${users}" | tr $'\n' ',' ) 187 | targets=$( USERGROUP_LIST_TARGETS "${usergroup}" ); targets=$( echo -n "${targets}" | tr $'\n' ',' ) 188 | echo " ${users} --- usergroup(${usergroup}) ---> ${targets}" 189 | 190 | return 0; 191 | } 192 | 193 | # usage: USERGROUP_ACCESS_NOTIFY 194 | # desc: Notify all users of the usergroup about their access list (via mail) 195 | USERGROUP_ACCESS_NOTIFY () { 196 | local usergroup= user= 197 | if [ $# -ne 1 ]; then 198 | BAD_ARGUMENTS ; return 1; 199 | fi 200 | 201 | usergroup="$1" 202 | if [ ! -f "${SSHGATE_DIR_USERS_GROUPS}/${usergroup}" -o -z "${usergroup}" ]; then 203 | ERROR "User group '${usergroup}' doesn't exist" ; return 1; 204 | fi 205 | 206 | for user in $( USERGROUP_LIST_USERS "${usergroup}" ); do 207 | USER_ACCESS_NOTIFY "${user}" 208 | done 209 | 210 | return 0; 211 | } 212 | 213 | fi # if [ "${__USERGROUP_FUNC__}" != 'Loaded' ]; then 214 | -------------------------------------------------------------------------------- /bin/sshgate-bridge: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # 3 | # Copyright (c) 2010 Linagora 4 | # Patrick Guiran 5 | # http://github.com/Tauop/sshGate 6 | # 7 | # sshGate is free software, you can redistribute it and/or modify 8 | # it under the terms of the GNU General Public License as 9 | # published by the Free Software Foundation; either version 2 of 10 | # the License, or (at your option) any later version. 11 | # 12 | # sshGate is distributed in the hope that it will be useful, 13 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | # GNU General Public License for more details. 16 | # 17 | # You should have received a copy of the GNU Lesser General Public License 18 | # along with this program. If not, see . 19 | # 20 | # ---------------------------------------------------------------------------- 21 | # VARIABLES used 22 | # - SSH_ORIGINAL_COMMAND : variable given by sshd, which contain the original 23 | # ssh command. 24 | # - SSHKEY_USER : the login of the connected user 25 | # - SFTP_SERVER : contant which containt the path to the sftp-server binary 26 | # - TARGET_HOST : target host of the sshg call 27 | # - TARGET_HOST_COMMAND : ssh command which will be exec on the ${TARGET_HOST} 28 | # - TARGET_LOGIN : login to use when connecting to the ${TARGET_HOST} 29 | # - ORIGINAL_TARGET_HOST : copy of TARGET_HOST used by error messages 30 | # ---------------------------------------------------------------------------- 31 | 32 | if [ $# -ne 1 -o -z "${1:-}" ]; then 33 | echo "your SSH KEY is not well configured. Please contact the sshGate administrator." 34 | exit 1 35 | fi 36 | 37 | # GLOBAL configuration ------------------------------------------------------- 38 | SSHKEY_USER="$1" 39 | 40 | # Load libraries ------------------------------------------------------------- 41 | load() { 42 | local var= value= file= 43 | 44 | var="$1"; file="$2" 45 | value=$( eval "echo \"\${${var}:-}\"" ) 46 | 47 | [ -n "${value}" ] && return 1; 48 | if [ -f "${file}" ]; then 49 | . "${file}" 50 | else 51 | echo "ERROR: Unable to load ${file}" 52 | exit 2 53 | fi 54 | return 0; 55 | } 56 | 57 | load SSHGATE_DIRECTORY '/etc/sshgate.conf' 58 | load SCRIPT_HELPER_DIRECTORY '/etc/scripthealper.conf' 59 | 60 | load __SSHGATE_SETUP__ "${SSHGATE_DIRECTORY}/data/sshgate.setup" 61 | load __SSHGATE_CORE__ "${SSHGATE_DIR_CORE}/sshgate.core" 62 | load __LIB_ASK__ "${SCRIPT_HELPER_DIRECTORY}/ask.lib.sh" 63 | load __LIB_RECORD__ "${SCRIPT_HELPER_DIRECTORY}/record.lib.sh" 64 | 65 | # little function ------------------------------------------------------------ 66 | mQUOTE() { printf "%s" "$1" | sed -e "s/^ *'//;s/' *$//;s/'/\\\'/g;s/^/'/;s/$/'/;"; } 67 | 68 | 69 | # determine action type (ssh or scp) and build TARGET_HOST ------------------- 70 | if [ "${SSH_ORIGINAL_COMMAND}" != "${SSH_ORIGINAL_COMMAND#/usr/libexec/openssh/sftp-server }" \ 71 | -o "${SSH_ORIGINAL_COMMAND}" != "${SSH_ORIGINAL_COMMAND#scp }" ]; then 72 | # SSH_ORIGNAL_COMMAND ends with the name of the target host 73 | TARGET_HOST=${SSH_ORIGINAL_COMMAND##* } 74 | 75 | if [ "${TARGET_HOST%%/*}" != "${TARGET_HOST}" ]; then 76 | SSH_ORIGINAL_COMMAND=${SSH_ORIGINAL_COMMAND%% ${TARGET_HOST}} 77 | target_files=${TARGET_HOST#*/} 78 | TARGET_HOST=${TARGET_HOST%%/*} 79 | if [ -z "${target_files}" -o "${target_files#/}" = "${target_files}" ]; then 80 | target_files="~/${target_files}" 81 | fi 82 | SSH_ORIGINAL_COMMAND="${SSH_ORIGINAL_COMMAND} ${target_files}" 83 | else 84 | SSH_ORIGINAL_COMMAND="${SSH_ORIGINAL_COMMAND%% ${TARGET_HOST}}" 85 | SSH_ORIGINAL_COMMAND="${SSH_ORIGINAL_COMMAND} ${TARGET_SCP_DIR}" 86 | fi 87 | action_type='scp' 88 | else 89 | # SSH_ORIGINAL_COMMAND starts with the name of the target host 90 | TARGET_HOST="${SSH_ORIGINAL_COMMAND%% *}" 91 | TARGET_HOST_COMMAND="${SSH_ORIGINAL_COMMAND##${TARGET_HOST}}" 92 | TARGET_HOST_COMMAND="${TARGET_HOST_COMMAND## }" 93 | action_type='ssh' 94 | fi 95 | 96 | # public commands ------------------------------------------------------------ 97 | if [ "${SSHGATE_ALLOW_REMOTE_COMMAND}" = 'Y' -a "${action_type}" = 'ssh' ]; then 98 | if [ "${TARGET_HOST}" = 'cmd' -o "${TARGET_HOST}" = 'cli' ]; then 99 | # inpired from ScriptHelper/cli.lib.sh 100 | # we don't want sshgate-bridge to be dependant on ScriptHelper 101 | BUILD_SED_CODE () { 102 | local sed_cmd= 103 | for word in $( echo "$1" | tr ' ' $'\n' ); do 104 | [ "${word}" = '?' ] && word="\([^ ]*\)" 105 | sed_cmd="${sed_cmd} *${word}" 106 | done 107 | echo -n "s|^${sed_cmd} *$|$2|p; t;" 108 | } 109 | is_admin=$( USER_GET_CONF "${SSHKEY_USER}" IS_ADMIN ) 110 | code= 111 | code="${code} $(BUILD_SED_CODE 'cmd list targets' 'USER_LIST_TARGETS ${SSHKEY_USER}' )" 112 | code="${code} $(BUILD_SED_CODE 'cmd list targets ?' 'USER_LIST_TARGETS \1' )" 113 | code="${code} $(BUILD_SED_CODE 'cmd user sshkey ?' 'USER_SSHKEY_DISPLAY \1' )" 114 | code="${code} $(BUILD_SED_CODE 'cmd target sshkey ?' 'TARGET_SSHKEY_DISPLAY \1' )" 115 | if [ "${SSHGATE_USE_REMOTE_ADMIN_CLI}" = 'Y' -a "${is_admin}" = 'true' ]; then 116 | code="${code} $(BUILD_SED_CODE 'cli' "sudo ${SSHGATE_DIR_BIN}/sshgate-cli -u '${SSHKEY_USER}'")" 117 | fi 118 | code="${code} a \ echo 'ERROR: unknown command' " 119 | eval $( echo "${SSH_ORIGINAL_COMMAND}" | sed -n -e "$code" ) 120 | exit 0; 121 | fi 122 | fi 123 | 124 | # check usage condition ------------------------------------------------------ 125 | if [ "${SSHGATE_USERS_MUST_ACCEPT_TOS}" = 'Y' ]; then 126 | USER_ACCEPTED_TOS "${SSHKEY_USER}" || exit 1 127 | fi 128 | 129 | 130 | # If user don't specify a target host, ask for the target host --------------- 131 | if [ -z "${TARGET_HOST}" ]; then 132 | echo "NOTICE: No target host given" 133 | read -p "Target host ? " TARGET_HOST 134 | TARGET_HOST=${TARGET_HOST%% *} 135 | fi 136 | 137 | # Determine information for connecting to the host --------------------------- 138 | ORIGINAL_TARGET_HOST="${TARGET_HOST}" 139 | TARGET_LOGIN=$( GET_LOGIN "${TARGET_HOST}" ) 140 | TARGET_HOST=$( GET_HOST "${TARGET_HOST}" ) 141 | 142 | TARGET_HOST=$( TARGET_REAL "${TARGET_HOST}" ) 143 | if [ -z "${TARGET_HOST}" ]; then 144 | echo "ERROR: Unknown host ${ORIGINAL_TARGET_HOST}." 145 | exit 1; 146 | fi 147 | 148 | # check ACL ------------------------------------------------------------------ 149 | if [ $( HAS_ACCESS "${SSHKEY_USER}" "${ORIGINAL_TARGET_HOST}" ) = 'false' ]; then 150 | echo "ERROR: The '${ORIGINAL_TARGET_HOST}' doesn't exist or you don't have access to it (or with login '${TARGET_LOGIN}')" 151 | exit 1 152 | fi 153 | 154 | # Do the stuff ;-) ----------------------------------------------------------- 155 | CURRENT_TIMESTAMP=$( date +%s ) 156 | SESSION_START "${CURRENT_TIMESTAMP}" "$$" "${SSHKEY_USER}" "${TARGET_HOST}" "${action_type}" "${SSH_ORIGINAL_COMMAND}" 157 | 158 | SSH_CONFIG_FILE= 159 | 160 | if [ "${action_type:-}" = 'ssh' ]; then 161 | SESSION_RECORD_FILE=$( SESSION_TARGET_GET_RECORD_FILE "${CURRENT_TIMESTAMP}" "${SSHKEY_USER}" "${TARGET_HOST}" ) 162 | SSH_CONFIG_FILE=$( TARGET_SSH_GET_CONFIG "${TARGET_HOST}" "${TARGET_LOGIN}" ) 163 | 164 | RECORD --file "${SESSION_RECORD_FILE}" "ssh -F $( mQUOTE "${SSH_CONFIG_FILE}" ) ${TARGET_HOST} -- $( mQUOTE "${TARGET_HOST_COMMAND}" )" 165 | RETURN_VALUE=$? 166 | else 167 | SSH_CONFIG_FILE=$( TARGET_SSH_GET_CONFIG "${TARGET_HOST}" "${TARGET_LOGIN}" ) 168 | 169 | ssh -F "${SSH_CONFIG_FILE}" ${TARGET_HOST} -- "${SSH_ORIGINAL_COMMAND}" 170 | RETURN_VALUE=$? 171 | fi 172 | 173 | rm -f "${SSH_CONFIG_FILE}" 174 | 175 | CURRENT_TIMESTAMP=$( date +%s ) 176 | SESSION_END "${CURRENT_TIMESTAMP}" "$$" "${SSHKEY_USER}" "${TARGET_HOST}" "${SESSION_RECORD_FILE:-}" 177 | 178 | exit ${RETURN_VALUE} 179 | -------------------------------------------------------------------------------- /bin/core/sshgate.core: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright (c) 2010 Linagora 3 | # Patrick Guiran 4 | # http://github.com/Tauop/sshGate 5 | # 6 | # sshGate is free software, you can redistribute it and/or modify 7 | # it under the terms of the GNU General Public License as 8 | # published by the Free Software Foundation; either version 2 of 9 | # the License, or (at your option) any later version. 10 | # 11 | # sshGate is distributed in the hope that it will be useful, 12 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | # GNU General Public License for more details. 15 | # 16 | # You should have received a copy of the GNU Lesser General Public License 17 | # along with this program. If not, see . 18 | # 19 | # README --------------------------------------------------------------------- 20 | # 21 | # Collection of all need functions to deal with sshgate administrations. 22 | # 23 | # ---------------------------------------------------------------------------- 24 | 25 | if [ "${__SSHGATE_CORE__:-}" != 'Loaded' ]; then 26 | __SSHGATE_CORE__='Loaded' 27 | 28 | load() { 29 | local var= value= file= 30 | 31 | var="$1"; file="$2" 32 | value=$( eval "echo \"\${${var}:-}\"" ) 33 | 34 | [ -n "${value}" ] && return 1; 35 | if [ -f "${file}" ]; then 36 | . "${file}" 37 | else 38 | echo "ERROR: Unable to load ${file}" 39 | exit 2 40 | fi 41 | return 0; 42 | } 43 | load SSHGATE_DIRECTORY '/etc/sshgate.conf' 44 | 45 | load __SSHGATE_SETUP__ "${SSHGATE_DIRECTORY}/data/sshgate.setup" 46 | load __LIB_RANDOM__ "${SCRIPT_HELPER_DIRECTORY}/random.lib.sh" 47 | load __LIB_MESSAGE__ "${SCRIPT_HELPER_DIRECTORY}/message.lib.sh" 48 | load __LIB_CONF__ "${SCRIPT_HELPER_DIRECTORY}/conf.lib.sh" 49 | load __LIB_ASK__ "${SCRIPT_HELPER_DIRECTORY}/ask.lib.sh" 50 | load __LIB_MUTEX__ "${SCRIPT_HELPER_DIRECTORY}/mutex.lib.sh" 51 | 52 | # load sub-core libraries 53 | load __USER_FUNC__ "${SSHGATE_DIR_CORE}/user.func" 54 | load __TARGET_FUNC__ "${SSHGATE_DIR_CORE}/target.func" 55 | load __TARGET_SSH_FUNC__ "${SSHGATE_DIR_CORE}/target-ssh.func" 56 | load __TARGET_SSHKEY_FUNC__ "${SSHGATE_DIR_CORE}/target-sshkey.func" 57 | load __TARGET_ACCESS_FUNC__ "${SSHGATE_DIR_CORE}/target-access.func" 58 | load __TARGET_KNOWN_HOSTS_FUNC__ "${SSHGATE_DIR_CORE}/target-known_hosts.func" 59 | load __USERGROUP_FUNC__ "${SSHGATE_DIR_CORE}/usergroup.func" 60 | load __RECORD_FUNC__ "${SSHGATE_DIR_CORE}/record.func" 61 | 62 | ERROR () { 63 | echo "ERROR: $*" 1>&2; 64 | } 65 | 66 | BAD_ARGUMENTS () { 67 | ERROR "Bad arguments"; 68 | } 69 | 70 | # usage: private_ACL_FILE_ADD 71 | private_ACL_FILE_ADD () { 72 | [ ! -f "$2" ] && touch "$2" # to avoid bugs 73 | grep "^$1\$" < "$2" >/dev/null 2>/dev/null 74 | [ $? -ne 0 ] && echo "$1" >> "$2" 75 | } 76 | 77 | # usage: private_ACL_FILE_DEL 78 | private_ACL_FILE_DEL () { 79 | local random=$( RANDOM ) 80 | [ ! -f "$2" ] && return 0; # to avoir bugs 81 | grep -v "^$1\$" < "$2" > "/tmp/file.${random}" 82 | mv "/tmp/file.${random}" "$2" 83 | } 84 | 85 | # usage: private_MAIL_APPEND 86 | private_MAIL_APPEND () { 87 | [ "${__LIB_MAIL__:-}" = 'Loaded' -a "${SSHGATE_MAIL_SEND:-}" = 'Y' ] && MAIL_APPEND "$*" 88 | } 89 | 90 | # usage: SSHGATE_ACCOUNT_HOMEDIR 91 | # desc: Echo-return the home directory of the SSHGATE_GATE_ACCOUNT user 92 | SSHGATE_ACCOUNT_HOMEDIR() { 93 | < /etc/passwd grep "^${SSHGATE_GATE_ACCOUNT}:" | cut -d':' -f6 94 | } 95 | 96 | # usage: GET_LOGIN 97 | # desc: Echo-return the login from a connection string 98 | # note: if the string doesn't contain the login : 99 | # - we try to get the DEFAULT_SSH_LOGIN of the host 100 | # - otherwise ${SSHGATE_TARGETS_DEFAULT_SSH_LOGIN}, if contain in login list of the host 101 | # - otherwise the first login available for the host 102 | # - empty string ( ERROR ) 103 | GET_LOGIN () { 104 | local string="$1" login= target= login_list= 105 | 106 | # the login is present in the connection string 107 | if [ "${string}" != "${string%%@*}" ]; then 108 | echo "${string%%@*}"; 109 | return 0; 110 | fi 111 | 112 | target=$( TARGET_REAL "${string}" ) 113 | if [ -n "${target}" ]; then 114 | login=$( TARGET_GET_CONF "${target}" DEFAULT_SSH_LOGIN ) 115 | if [ -z "${login}" ]; then 116 | login=$( TARGET_SSH_LIST_LOGINS "${target}" | grep "${SSHGATE_TARGETS_DEFAULT_SSH_LOGIN}" ) 117 | fi 118 | fi 119 | [ -n "${login}" ] && echo "${login}" || echo "${SSHGATE_TARGETS_DEFAULT_SSH_LOGIN}" 120 | 121 | return 0; 122 | } 123 | 124 | # usage: GET_HOST 125 | # desc: Echo-return the host from a connection string 126 | GET_HOST () { 127 | echo "${1#*@}"| tr '[:upper:]' '[:lower:]'; return 0; 128 | } 129 | 130 | # usage: HAS_ACCESS [@] 131 | # desc: Tell if a user has access to a taret host 132 | # note: Echo-return 'true' if the user is allowed to access to the target host, 'false' otherwise 133 | # note: if no is given, use ${SSHGATE_TARGETS_DEFAULT_SSH_LOGIN} 134 | HAS_ACCESS () { 135 | local user= target= login= is_admin= is_restricted= 136 | 137 | if [ $# -ne 2 ]; then 138 | BAD_ARGUMENTS ; return 1; 139 | fi 140 | 141 | user="$1"; target="$2" 142 | login=$( GET_LOGIN "${target}" ) 143 | 144 | target=$( TARGET_REAL "${target}" ) 145 | if [ -z "${user}" -o -z "${target}" ]; then 146 | echo 'false'; return 1; 147 | fi 148 | 149 | is_admin=$( USER_GET_CONF "${user}" IS_ADMIN ) 150 | is_restricted=$( USER_GET_CONF "${user}" IS_RESTRICTED ) 151 | 152 | if [ "${is_admin}" = 'true' -o "${is_restricted}" = 'false' ]; then 153 | TARGET_SSH_LIST_LOGINS "${target}" | grep "^${login}$" >/dev/null 154 | if [ $? -eq 0 ]; then 155 | echo 'true'; return 0; 156 | else 157 | echo 'false'; return 1; 158 | fi 159 | fi 160 | 161 | TARGET_ACCESS_LIST_USERS "${target}" "${login}" | grep "^${user}$" >/dev/null 162 | if [ $? -eq 0 ]; then 163 | echo 'true'; return 0; 164 | fi 165 | echo 'false'; return 1; 166 | } 167 | 168 | # usage: EDIT_FILE 169 | # desc: Open a file with ${SSHGATE_EDITOR} to be edit 170 | # return: 0 on success, otherwise 1 171 | # note: can failed if ${SSHGATE_EDITOR} is empty and ${EDITOR} is empty too 172 | EDIT_FILE() { 173 | local the_editor= file= good= message_done= 174 | 175 | if [ $# -ne 1 ]; then 176 | BAD_ARGUMENTS ; return 1; 177 | fi 178 | 179 | file="$1" 180 | if [ ! -f "${file}" ]; then 181 | ERROR "The file ${file} doesn't exist"; return 1; 182 | fi 183 | 184 | the_editor="${SSHGATE_EDITOR:-${EDITOR}}" 185 | 186 | # don't check for the binary existance if we are testing 187 | if [ "${SSHGATE_TEST:-}" != 'sshGateTest' ]; then 188 | message_done='false' 189 | while [ true ]; do 190 | which "${the_editor}" >/dev/null 2>/dev/null 191 | [ $? -eq 0 ] && break; 192 | BR 193 | WARNING "sshGate can't find a editor. Provide a editor to use for the moment." 194 | if [ "${message_done}" = 'false' ]; then 195 | NOTICE "Ask the sshGate super-administrator (root unix account) to configure" 196 | MESSAGE "sshGate via sshgate-configure or configure your \${EDITOR} environment variable" 197 | BR 198 | message_done='true' 199 | fi 200 | ASK the_editor "Editor to use for now : " 201 | done 202 | fi 203 | 204 | eval "${the_editor} '${file}'" 205 | return $? 206 | } 207 | 208 | fi # __SSHGATE_CORE__ 209 | -------------------------------------------------------------------------------- /tests/target.testcase: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright (c) 2010 Linagora 3 | # Patrick Guiran 4 | # http://github.com/Tauop/ScriptHelper 5 | # 6 | # ScriptHelper is free software, you can redistribute it and/or modify 7 | # it under the terms of the GNU General Public License as 8 | # published by the Free Software Foundation; either version 2 of 9 | # the License, or (at your option) any later version. 10 | # 11 | # ScriptHelper is distributed in the hope that it will be useful, 12 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | # GNU General Public License for more details. 15 | # 16 | # You should have received a copy of the GNU Lesser General Public License 17 | # along with this program. If not, see . 18 | # 19 | # -------------------------------------------------------------------------- 20 | 21 | mDOTHIS 'Generate target tests' 22 | 23 | hostname=$( hostname | tr '[:upper:]' '[:lower:]' ) 24 | alias="${hostname}2" 25 | ip=$( hostname -i ) 26 | 27 | cat >"${expected_test_file}" < target list 29 | 30 | sshGate > target add ${hostname} 31 | Use the sshGate default sshkey for this target host [Y] ? Y 32 | <<=Y 33 | sshGate > target add ${ip} 34 | Use the sshGate default sshkey for this target host [Y] ? N 35 | <<=N 36 | $(cat "${sshkey_priv_test_file}" | while read line ; do echo "<<-${line}"; done; echo "->>" ) 37 | sshGate > target list 38 | ${ip} 39 | ${hostname} 40 | sshGate > target list ${hostname%??}* 41 | ${hostname} 42 | sshGate > target alias list 43 | sshGate > target ${hostname} add alias ${alias} 44 | sshGate > target alias list ${hostname} 45 | ${alias} 46 | sshGate > target alias list 47 | ${alias} 48 | sshGate > target ${hostname} list alias 49 | ${alias} 50 | sshGate > target ${alias} realname 51 | ${hostname} 52 | sshGate > target ${hostname} del alias ${alias} 53 | sshGate > target ${hostname} list alias 54 | sshGate > target ${ip} rename ${alias} 55 | Target renamed : ${ip} -> ${alias} 56 | Target alias '${ip}' created 57 | sshGate > target alias list 58 | ${ip} 59 | sshGate > target ${hostname} display conf 60 | NOTICE: Target host '${hostname}' has no configuration file 61 | sshGate > target ${ip} set conf DEFAULT_SSH_LOGIN ${user_unix_test_account} 62 | sshGate > target ${alias} display conf 63 | DEFAULT_SSH_LOGIN="${user_unix_test_account}" 64 | sshGate > target ${hostname} 65 | sshGate [target ${hostname}]> set conf DEFAULT_SSH_LOGIN ${user_unix_test_account} 66 | sshGate [target ${hostname}]> ssh test 67 | - ${user_unix_test_account}@${hostname} ... OK 68 | sshGate [target ${hostname}]> ssh add login root 69 | sshGate [target ${hostname}]> ssh list logins 70 | root 71 | ${user_unix_test_account} 72 | sshGate [target ${hostname}]> quit 73 | sshGate > target ssh test all 74 | = Test all targets ssh connectivity = 75 | - root@${hostname} ... KO 76 | Permission denied (publickey,password). 77 | - ${user_unix_test_account}@${hostname} ... OK 78 | - ${user_unix_test_account}@${alias} ... KO 79 | ssh: Could not resolve hostname ${alias}: Name or service not known 80 | sshGate > target ${hostname} ssh edit key 81 | Use the sshGate default sshkey for this target host [Y] ? Y 82 | <<=Y 83 | sshGate > target ${hostname} ssh edit key 84 | Use the sshGate default sshkey for this target host [Y] ? N 85 | <<=N 86 | $(cat "${sshkey_priv_test_file}" | while read line ; do echo "<<-${line}"; done; echo "->>" ) 87 | sshGate > target ${hostname} ssh display key 88 | # public sshkey of ${hostname} 89 | $( cat "${sshkey_pub_test_file}" ) 90 | sshGate > target ${hostname} ssh use default key 91 | sshGate > target ${hostname} ssh display key 92 | # public sshkey of ${hostname} 93 | $( cat "${SSHGATE_TARGET_DEFAULT_PUBLIC_SSHKEY_FILE}" ) 94 | sshGate > target ${user_unix_test_account}@${hostname} ssh install key 95 | sshGate > target ssh update known_hosts 96 | - ${hostname} ... OK 97 | - ${hostname}2 ... KO 98 | sshGate > target ${hostname} ssh update known_hosts 99 | sshGate > target ssh display config 100 | sshGate > target ssh edit config 101 | <<-User root 102 | ->> 103 | WARNING: ssh options 'User' was removed from editable configuration file. It's not allowed or deal by sshGate 104 | sshGate > target ssh display config 105 | sshGate > target ssh edit config 106 | <<-ConnectTimeout 10 107 | ->> 108 | sshGate > target ssh display config 109 | ConnectTimeout 10 110 | sshGate > target root@${hostname} ssh edit config 111 | <<-ConnectTimeout 30 112 | <<-ForwardX11 yes 113 | ->> 114 | sshGate > target root@${hostname} ssh display config 115 | ConnectTimeout 30 116 | ForwardX11 yes 117 | sshGate > target root@${hostname} ssh display full config 118 | Host * 119 | IdentityFile ${SSHGATE_TARGET_DEFAULT_PRIVATE_SSHKEY_FILE} 120 | IdentitiesOnly yes 121 | PasswordAuthentication no 122 | StrictHostKeyChecking yes 123 | HashKnownHosts no 124 | UserKnownHostsFile $(SSHGATE_ACCOUNT_HOMEDIR)/.ssh/known_hosts 125 | ConnectTimeout 10 126 | 127 | Host ${hostname} 128 | IdentityFile ${SSHGATE_TARGET_DEFAULT_PRIVATE_SSHKEY_FILE} 129 | IdentitiesOnly yes 130 | PasswordAuthentication no 131 | StrictHostKeyChecking yes 132 | User root 133 | ConnectTimeout 30 134 | ForwardX11 yes 135 | sshGate > target ${hostname} set conf SSH_PROXY ${user_unix_test_account}@${alias} 136 | sshGate > target ${hostname} display conf 137 | DEFAULT_SSH_LOGIN="${user_unix_test_account}" 138 | SSH_PROXY="${user_unix_test_account}@${alias}" 139 | sshGate > target root@${hostname} ssh display full config 140 | Host * 141 | IdentityFile ${SSHGATE_TARGET_DEFAULT_PRIVATE_SSHKEY_FILE} 142 | IdentitiesOnly yes 143 | PasswordAuthentication no 144 | StrictHostKeyChecking yes 145 | HashKnownHosts no 146 | UserKnownHostsFile $(SSHGATE_ACCOUNT_HOMEDIR)/.ssh/known_hosts 147 | ConnectTimeout 10 148 | 149 | Host ${alias} 150 | IdentityFile ${SSHGATE_DIR_TARGETS}/${alias}/sshkey.priv 151 | IdentitiesOnly yes 152 | PasswordAuthentication no 153 | StrictHostKeyChecking yes 154 | User ${user_unix_test_account} 155 | 156 | Host ${hostname} 157 | IdentityFile ${SSHGATE_TARGET_DEFAULT_PRIVATE_SSHKEY_FILE} 158 | IdentitiesOnly yes 159 | PasswordAuthentication no 160 | StrictHostKeyChecking yes 161 | User root 162 | ProxyCommand ssh -F ssh_conf_file ${user_unix_test_account}@${alias} nc %h %p 163 | ConnectTimeout 30 164 | ForwardX11 yes 165 | sshGate > target ${hostname} del conf SSH_PROXY 166 | sshGate > target ${hostname} display conf 167 | DEFAULT_SSH_LOGIN="${user_unix_test_account}" 168 | sshGate > target ${hostname} ssh del login root 169 | sshGate > target ${hostname} ssh list logins 170 | ${user_unix_test_account} 171 | sshGate > target del ${ip} 172 | sshGate > target alias list 173 | sshGate > target list 174 | ${hostname} 175 | sshGate > target ssh install all key 176 | = Install sshkey on all targets = 177 | . ${user_unix_test_account}@${hostname} ... OK 178 | sshGate > target add ${ip} with proxy ${hostname} 179 | Use the sshGate default sshkey for this target host [Y] ? Y 180 | <<=Y 181 | sshGate > exit 182 | EOF 183 | 184 | grep -E '^(<<=|<<-|->>|sshGate [^>]*>)' < "${expected_test_file}" \ 185 | | sed -e 's/^sshGate [^>]*> //; s/^<<=//;' > "${input_test_file}" 186 | 187 | tmp_file="${expected_test_file}.$(RANDOM)" 188 | grep -v -E '^(<<=|<<-|->>)' < "${expected_test_file}" > "${tmp_file}" 189 | mv "${tmp_file}" "${expected_test_file}" 190 | 191 | mOK 192 | 193 | # -------------------------------------------------------------------------- 194 | mDOTHIS 'Launch target tests' 195 | ASK_SET_AUTOANSWER_FILE "${input_test_file}" 196 | ( CLI_RUN > "${output_test_file}" 4 | # http://github.com/Tauop/sshGate 5 | # 6 | # sshGate is free software, you can redistribute it and/or modify 7 | # it under the terms of the GNU General Public License as 8 | # published by the Free Software Foundation; either version 2 of 9 | # the License, or (at your option) any later version. 10 | # 11 | # sshGate is distributed in the hope that it will be useful, 12 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | # GNU General Public License for more details. 15 | # 16 | # You should have received a copy of the GNU Lesser General Public License 17 | # along with this program. If not, see . 18 | # 19 | # README --------------------------------------------------------------------- 20 | # 21 | # Collection of all sshkey of target related functions 22 | # 23 | # ---------------------------------------------------------------------------- 24 | 25 | if [ "${__SSHGATE_CORE__}" != 'Loaded' ]; then 26 | echo "ERROR: Only sshgate.core can load user.func."; exit 1; 27 | fi 28 | 29 | if [ "${__TARGET_SSHKEY_FUNC__:-}" != 'Loaded' ]; then 30 | __TARGET_SSHKEY_FUNC__='Loaded' 31 | 32 | # usage: TARGET_SSHKEY_EDIT 33 | # desc: edit the private sshkey of a target 34 | TARGET_SSHKEY_EDIT () { 35 | local target= privkey= pubkey= tmpfile= 36 | 37 | if [ $# -ne 1 ]; then 38 | BAD_ARGUMENTS ; return 1; 39 | fi 40 | 41 | target=$( TARGET_REAL "$1" ) 42 | if [ -z "${target}" ]; then 43 | ERROR "Target host '${target}' doesn't exist"; return 1 44 | fi 45 | 46 | privkey="${SSHGATE_DIR_TARGETS}/${target}/${SSHGATE_TARGET_PRIVATE_SSHKEY_FILENAME}" 47 | pubkey="${SSHGATE_DIR_TARGETS}/${target}/${SSHGATE_TARGET_PUBLIC_SSHKEY_FILENAME}" 48 | tmpfile="/tmp/file.$(RANDOM)" 49 | 50 | ASK --yesno reply 'Use the sshGate default sshkey for this target host [Y] ? ' 51 | if [ "${reply}" = 'Y' ]; then 52 | rm -f "${privkey}" "${pubkey}" >/dev/null 2>/dev/null 53 | return 0; 54 | fi 55 | 56 | touch "${privkey}" "${pubkey}" "${tmpfile}" 2>/dev/null 57 | if [ $? -ne 0 ]; then 58 | ERROR "Can't write sshkey files"; return 1; 59 | fi 60 | 61 | echo "# Put the private sshkey for '${target}' here. Then save & quit from the editor" >> "${tmpfile}" 62 | echo "# line begins by '#' will be removed" >> "${tmpfile}" 63 | EDIT_FILE "${tmpfile}" 64 | if [ $? -ne 0 ]; then 65 | ERROR "Can't edit sshkey file"; return 1; 66 | fi 67 | 68 | grep -v '^#' < "${tmpfile}" > "${privkey}" 69 | chown "${SSHGATE_GATE_ACCOUNT}" "${privkey}" 70 | chmod 400 "${privkey}" 71 | 72 | # try to generate the public key, to check that the key doesn't have passphrase 73 | ssh-keygen -y -N '' -f "${privkey}" > "${tmpfile}" 74 | if [ $? -ne 0 ]; then 75 | rm -rf "${tmpfile}" "${privkey}" "${pubkey}" 76 | ERROR "Unable to generate public ssh key." ; return 1; 77 | fi 78 | 79 | tr -d $'\n' < "${tmpfile}" > "${pubkey}" 80 | echo " sshGate key" >> "${pubkey}" 81 | 82 | chown "${SSHGATE_GATE_ACCOUNT}" "${pubkey}" 83 | 84 | rm -f "${tmpfile}" 85 | return 0; 86 | } 87 | 88 | # usage: DISPLAY_TARGET_PUBLIC_SSHKEY 89 | # desc: Display public sshkey of a target 90 | TARGET_SSHKEY_DISPLAY () { 91 | local target= 92 | if [ $# -ne 1 ]; then 93 | BAD_ARGUMENTS ; return 1; 94 | fi 95 | target=$( TARGET_REAL "$1" ) 96 | if [ -z "${target}" ]; then 97 | ERROR "Target host '${target}' doesn't exist"; return 1; 98 | fi 99 | echo "# public sshkey of ${target}" 100 | cat $( private_TARGET_PUBLIC_SSHKEY_FILE "${target}" ) 101 | return 0; 102 | } 103 | 104 | # usage: TARGET_SSHKEY_USE_DEFAULT 105 | # desc: Set default sshkey for a target host 106 | # note: you may have access to the with the sshkey of the 107 | # root account, or with the your sshkey and sshagent forwarding. 108 | TARGET_SSHKEY_USE_DEFAULT () { 109 | local target= 110 | if [ $# -ne 1 ]; then 111 | BAD_ARGUMENTS ; return 1; 112 | fi 113 | 114 | target=$( TARGET_REAL "$1" ) 115 | if [ -z "${target}" ]; then 116 | ERROR "Target host '${target}' doesn't exist" ; return 1; 117 | fi 118 | 119 | sshkey_file=$( private_TARGET_PUBLIC_SSHKEY_FILE "${target}" ) 120 | [ "${sshkey_file}" != "${SSHGATE_TARGET_DEFAULT_PUBLIC_SSHKEY_FILE}" ] && rm -f "${sshkey_file}" 121 | 122 | sshkey_file=$( private_TARGET_PRIVATE_SSHKEY_FILE "${target}" ) 123 | [ "${sshkey_file}" != "${SSHGATE_TARGET_DEFAULT_PRIVATE_SSHKEY_FILE}" ] && rm -f "${sshkey_file}" 124 | 125 | return 0; 126 | } 127 | 128 | # usage: TARGET_SSHKEY_INSTALL [@] 129 | # usage: TARGET_SSHKEY_INSTALL [] 130 | # desc: Try to install public sshkey on all targets 131 | # note: you may have access to the with the sshkey of the 132 | # root account, or with the your sshkey and sshagent forwarding. 133 | # note: if isn't specified, use the target's default ssh login 134 | TARGET_SSHKEY_INSTALL () { 135 | local target= login= sshkey_file= ssh_conf_file= 136 | if [ $# -ne 1 -a $# -ne 2 ]; then 137 | BAD_ARGUMENTS ; return 1; 138 | fi 139 | 140 | if [ $# -eq 1 ]; then 141 | target=$( GET_HOST "$1" ) 142 | login=$( GET_LOGIN "$1" ) 143 | else 144 | target="$1"; login="$2" 145 | fi 146 | 147 | target=$( TARGET_REAL "${target}" ) 148 | if [ -z "${target}" ]; then 149 | ERROR "Target host '${target}' doesn't exist" ; return 1; 150 | fi 151 | 152 | sshkey_file=$( private_TARGET_PUBLIC_SSHKEY_FILE "${target}" ) 153 | if [ -z "${sshkey_file}" ]; then 154 | ERROR "Unable to find private ssh key of '${target}'" ; return 1; 155 | fi 156 | 157 | cat "${sshkey_file}" \ 158 | | TARGET_SSH_RUN_COMMAND "${login}@${target}" "umask 077; test -d .ssh || mkdir .ssh ; cat >> .ssh/authorized_keys" 159 | if [ $? -ne 0 ]; then 160 | echo "NOTICE: Public ssh key of '${target}' can't be installed on '${login}@${target}'. Install it manually" 161 | fi 162 | 163 | return 0 164 | } 165 | 166 | # usage: TARGET_SSHKEY_INSTALL_ALL 167 | # desc: Try to install the public sshkey on the target 168 | # note: you may have access to the with the sshkey of the 169 | # root account, or with the your sshkey and sshagent forwarding. 170 | TARGET_SSHKEY_INSTALL_ALL () { 171 | echo "= Install sshkey on all targets =" 172 | for target in $( TARGETS_LIST ); do 173 | for login in $( TARGET_SSH_LIST_LOGINS "${target}" ); do 174 | echo -n ". ${login}@${target} ... " 175 | TARGET_SSHKEY_INSTALL "${login}@${target}" 176 | [ $? -eq 0 ] && echo 'OK' || echo 'KO' 177 | done 178 | done 179 | return 0; 180 | } 181 | 182 | # usage: private_TARGET_PRIVATE_SSHKEY_FILE 183 | # desc: echo-return the path to the private ssh key of the target host 184 | private_TARGET_PRIVATE_SSHKEY_FILE () { 185 | local target= f= 186 | if [ $# -ne 1 ]; then 187 | BAD_ARGUMENTS ; return 1; 188 | fi 189 | target="$1" 190 | f="${SSHGATE_DIR_TARGETS}/${target}/${SSHGATE_TARGET_PRIVATE_SSHKEY_FILENAME}" 191 | [ ! -r "$f" -o -z "${target}" ] && f="${SSHGATE_TARGET_DEFAULT_PRIVATE_SSHKEY_FILE}" 192 | echo "$f" 193 | } 194 | 195 | # usage: private_TARGET_PUBLIC_SSHKEY_FILE 196 | # desc: echo-return the path to the public ssh key of the target host 197 | private_TARGET_PUBLIC_SSHKEY_FILE () { 198 | local target= f= 199 | if [ $# -ne 1 ]; then 200 | BAD_ARGUMENTS ; return 1; 201 | fi 202 | target="$1" 203 | f="${SSHGATE_DIR_TARGETS}/${target}/${SSHGATE_TARGET_PUBLIC_SSHKEY_FILENAME}" 204 | [ ! -r "$f" -o -z "${target}" ] && f="${SSHGATE_TARGET_DEFAULT_PUBLIC_SSHKEY_FILE}" 205 | echo "$f" 206 | } 207 | 208 | fi # end of: if [ "${__TARGET_SSHKEY_FUNC__:-}" != 'Loaded' ]; then 209 | -------------------------------------------------------------------------------- /tests/test.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # 3 | # Copyright (c) 2010 Linagora 4 | # Patrick Guiran 5 | # http://github.com/Tauop/ScriptHelper 6 | # 7 | # ScriptHelper is free software, you can redistribute it and/or modify 8 | # it under the terms of the GNU General Public License as 9 | # published by the Free Software Foundation; either version 2 of 10 | # the License, or (at your option) any later version. 11 | # 12 | # ScriptHelper is distributed in the hope that it will be useful, 13 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | # GNU General Public License for more details. 16 | # 17 | # You should have received a copy of the GNU Lesser General Public License 18 | # along with this program. If not, see . 19 | # 20 | 21 | load() { 22 | local var= value= file= 23 | 24 | var="$1"; file="$2" 25 | value=$( eval "echo \"\${${var}:-}\"" ) 26 | 27 | [ -n "${value}" ] && return 1; 28 | if [ -f "${file}" ]; then 29 | . "${file}" 30 | else 31 | echo "ERROR: Unable to load ${file}" 32 | exit 2 33 | fi 34 | return 0; 35 | } 36 | 37 | load SSHGATE_DIRECTORY '/etc/sshgate.conf' 38 | load __SSHGATE_SETUP__ "${SSHGATE_DIRECTORY}/data/sshgate.setup" 39 | 40 | 41 | testcases=$( find "${SSHGATE_DIR_BIN}/tests/" -type f -iname "*.testcase" -printf "%P\n" \ 42 | | sed -e 's/^\(.*\)[.]testcase$/\1/' ) 43 | 44 | usage () { 45 | testcases=$( echo -n "${testcases}" | tr $'\n' ',' | sed -e 's/,/, /g' ) 46 | echo "Usage: $0 " 47 | echo " : all, ${testcases}" | fold -s 48 | exit 1 49 | } 50 | 51 | if [ $# -ne 1 ]; then 52 | echo 'ERROR: Bad arguments' 53 | usage 54 | fi 55 | 56 | TEST_CASE="$1" 57 | TEST_CASE_DIR="${SSHGATE_DIR_BIN}/tests" 58 | 59 | if [ "${TEST_CASE}" != 'all' ]; then 60 | TEST_CASE="${TEST_CASE_DIR}/${TEST_CASE}.testcase" 61 | 62 | if [ ! -r "${TEST_CASE}" ]; then 63 | echo 'ERROR: unknown test-case' 64 | usage 65 | fi 66 | fi 67 | 68 | # don't use function.lib.sh functions ! 69 | mDOTHIS() { echo -n "- $* ... "; } 70 | mOK() { echo 'OK'; } 71 | 72 | # tell sshGate module we are making tests :-) 73 | SSHGATE_TEST='sshGateTest' 74 | 75 | # -------------------------------------------------------------------------- 76 | mDOTHIS 'Loading sshGate core' 77 | load __SSHGATE_CLI__ "${SSHGATE_DIR_BIN}/sshgate-cli" 78 | load __LIB_RANDOM__ "${SCRIPT_HELPER_DIRECTORY}/random.lib.sh" 79 | mOK 80 | 81 | # -------------------------------------------------------------------------- 82 | mDOTHIS 'Setup sshGate data directory' 83 | # get from sshgate.conf 84 | SSHGATE_DIRECTORY="/tmp/sshgate.$(RANDOM)" 85 | SSHGATE_DIR_DATA="${SSHGATE_DIRECTORY}/data" 86 | SSHGATE_DIR_BIN="${SSHGATE_DIRECTORY}/bin" 87 | SSHGATE_DIR_CORE="${SSHGATE_DIRECTORY}/core" 88 | SSHGATE_DIR_USERS="${SSHGATE_DIRECTORY}/users" 89 | SSHGATE_DIR_TARGETS="${SSHGATE_DIRECTORY}/targets" 90 | SSHGATE_DIR_USERS_GROUPS="${SSHGATE_DIRECTORY}/users.groups" 91 | SSHGATE_DIR_LOGS="${SSHGATE_DIRECTORY}/logs" 92 | SSHGATE_DIR_LOGS_TARGETS="${SSHGATE_DIR_LOGS}/targets-logs" 93 | SSHGATE_DIR_LOGS_USERS="${SSHGATE_DIR_LOGS}/users-logs" 94 | SSHGATE_DIR_ARCHIVE="${SSHGATE_DIRECTORY}/archives" 95 | SSHGATE_LOGS_CURRENT_SESSION_FILE="${SSHGATE_DIR_LOGS}/current_session.log" 96 | 97 | # get from install.sh 98 | MK () { [ ! -d "$1/" ] && mkdir -p "$1"; } 99 | MK "${SSHGATE_DIRECTORY}" 100 | MK "${SSHGATE_DIR_DATA}" 101 | MK "${SSHGATE_DIR_BIN}" 102 | MK "${SSHGATE_DIR_CORE}" 103 | MK "${SSHGATE_DIR_USERS}" 104 | MK "${SSHGATE_DIR_TARGETS}" 105 | MK "${SSHGATE_DIR_USERS_GROUPS}" 106 | MK "${SSHGATE_DIR_LOGS_TARGETS}" 107 | MK "${SSHGATE_DIR_LOGS_USERS}" 108 | MK "${SSHGATE_DIR_ARCHIVE}" 109 | mOK 110 | 111 | # -------------------------------------------------------------------------- 112 | mDOTHIS 'Generate temporary test file' 113 | input_test_file="/tmp/test_sshgate_input.$(RANDOM)" 114 | output_test_file="/tmp/test_sshgate_output.$(RANDOM)" 115 | expected_test_file="/tmp/test_sshgate_expected.$(RANDOM)" 116 | sshkey_priv_test_file="/tmp/test_sshgate_sshkey.$(RANDOM)" 117 | sshkey_pub_test_file="${sshkey_priv_test_file}.pub" 118 | sshkey_priv_unix_test_file="/tmp/test_sshgate_sshkey_unix.$(RANDOM)" 119 | sshkey_pub_unix_test_file="${sshkey_priv_unix_test_file}.pub" 120 | mOK 121 | 122 | # -------------------------------------------------------------------------- 123 | mDOTHIS 'Generate temporary sshkey test file' 124 | # generate fake ssh keys pair without passphrase 125 | ssh-keygen -C "sshGate key" -t rsa -b 1024 -N '' -f "${sshkey_priv_test_file}" >/dev/null 126 | ssh-keygen -C "user@key" -t rsa -b 1024 -N '' -f "${sshkey_priv_unix_test_file}" >/dev/null 127 | chmod 400 "${sshkey_priv_test_file}" 128 | chmod 400 "${sshkey_priv_unix_test_file}" 129 | mOK 130 | 131 | # -------------------------------------------------------------------------- 132 | mDOTHIS 'Create and setup temporary Unix account' 133 | sshgate_unix_test_account="sshgate$(RANDOM)" 134 | useradd --home "/home/${sshgate_unix_test_account}" "${sshgate_unix_test_account}" 135 | mkdir -p "/home/${sshgate_unix_test_account}/.ssh/" 136 | cp "${sshkey_pub_unix_test_file}" "/home/${sshgate_unix_test_account}/.ssh/authorized_keys2" 137 | chown -R "${sshgate_unix_test_account}" "/home/${sshgate_unix_test_account}" 138 | 139 | user_unix_test_account="user$(RANDOM)" 140 | useradd --home "/home/${user_unix_test_account}" "${user_unix_test_account}" 141 | mkdir -p "/home/${user_unix_test_account}/.ssh/" 142 | cp "${sshkey_pub_unix_test_file}" "/home/${user_unix_test_account}/.ssh/authorized_keys2" 143 | chown -R "${user_unix_test_account}" "/home/${user_unix_test_account}" 144 | 145 | # change sshGate settings 146 | SSHGATE_GATE_ACCOUNT="${sshgate_unix_test_account}" 147 | SSHGATE_TARGETS_DEFAULT_SSH_LOGIN="${user_unix_test_account}" 148 | 149 | # need to read lines prefixed by "<<-" from ${expected_test_file}/${input_test_file}. 150 | # it ends when ASK read '->>' string 151 | SSHGATE_EDITOR='input=""; 152 | while true; do 153 | ASK --no-print --no-echo --allow-empty input 154 | input="${input#"<<-"}" 155 | if [ "${input}" != "${input#"<<="}" ]; then 156 | echo "${input#"<<="}"; break; 157 | fi 158 | [ "${input}" != "->>" ] && echo "${input}" 159 | [ "${input}" = "->>" ] && break; 160 | done >>' 161 | 162 | # install unix user sshkey to sshGate default key so that we can call TARGET_ADD 163 | # and TARGET_SSHKEY_INSTALL without problems 164 | SSHGATE_TARGET_DEFAULT_PRIVATE_SSHKEY_FILE="${SSHGATE_DIR_DATA}/${SSHGATE_TARGET_PRIVATE_SSHKEY_FILENAME}" 165 | SSHGATE_TARGET_DEFAULT_PUBLIC_SSHKEY_FILE="${SSHGATE_DIR_DATA}/${SSHGATE_TARGET_PUBLIC_SSHKEY_FILENAME}" 166 | cp "${sshkey_priv_unix_test_file}" "${SSHGATE_TARGET_DEFAULT_PRIVATE_SSHKEY_FILE}" 167 | cp "${sshkey_pub_unix_test_file}" "${SSHGATE_TARGET_DEFAULT_PUBLIC_SSHKEY_FILE}" 168 | mOK 169 | 170 | 171 | # -------------------------------------------------------------------------- 172 | 173 | if [ "${TEST_CASE}" != 'all' ]; then 174 | # Load the test-case 175 | . "${TEST_CASE}" 176 | else 177 | for test in ${testcases}; do 178 | mDOTHIS 'Reset temporary test file' 179 | echo -n '' > "${input_test_file}" 180 | echo -n '' > "${output_test_file}" 181 | echo -n '' > "${expected_test_file}" 182 | mOK 183 | mDOTHIS 'Reset sshGate data directories' 184 | rm -rf "${SSHGATE_DIRECTORY}" 185 | MK "${SSHGATE_DIRECTORY}" 186 | MK "${SSHGATE_DIR_DATA}" 187 | MK "${SSHGATE_DIR_BIN}" 188 | MK "${SSHGATE_DIR_CORE}" 189 | MK "${SSHGATE_DIR_USERS}" 190 | MK "${SSHGATE_DIR_TARGETS}" 191 | MK "${SSHGATE_DIR_USERS_GROUPS}" 192 | MK "${SSHGATE_DIR_LOGS}" 193 | MK "${SSHGATE_DIR_ARCHIVE}" 194 | cp "${sshkey_priv_unix_test_file}" "${SSHGATE_TARGET_DEFAULT_PRIVATE_SSHKEY_FILE}" 195 | cp "${sshkey_pub_unix_test_file}" "${SSHGATE_TARGET_DEFAULT_PUBLIC_SSHKEY_FILE}" 196 | mOK 197 | TEST_CASE="${TEST_CASE_DIR}/${test}.testcase" 198 | . "${TEST_CASE}" 199 | done 200 | fi 201 | 202 | # -------------------------------------------------------------------------- 203 | mDOTHIS 'Remove tests data' 204 | userdel "${sshgate_unix_test_account}" 205 | userdel "${user_unix_test_account}" 206 | [ -d "/home/${sshgate_unix_test_account}/" ] && rm -rf "/home/${sshgate_unix_test_account}" 207 | [ -d "/home/${user_unix_test_account}/" ] && rm -rf "/home/${user_unix_test_account}" 208 | 209 | mail_test_file=$( MAIL_GET_FILE ) 210 | rm -f "${input_test_file}" "${output_test_file}" "${expected_test_file}" 211 | rm -f "${sshkey_priv_test_file}" "${sshkey_pub_test_file}" 212 | rm -f "${sshkey_priv_unix_test_file}" "${sshkey_pub_unix_test_file}" 213 | rm -f "${mail_test_file}" 214 | rm -rf "${SSHGATE_DIRECTORY}" 215 | mOK 216 | exit 0 217 | -------------------------------------------------------------------------------- /bin/sshgate-cli: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # 3 | # Copyright (c) 2010 Linagora 4 | # Patrick Guiran 5 | # http://github.com/Tauop/sshGate 6 | # 7 | # sshGate is free software, you can redistribute it and/or modify 8 | # it under the terms of the GNU General Public License as 9 | # published by the Free Software Foundation; either version 2 of 10 | # the License, or (at your option) any later version. 11 | # 12 | # sshGate is distributed in the hope that it will be useful, 13 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | # GNU General Public License for more details. 16 | # 17 | # You should have received a copy of the GNU Lesser General Public License 18 | # along with this program. If not, see . 19 | # 20 | 21 | load() { 22 | local var= value= file= 23 | 24 | var="$1"; file="$2" 25 | value=$( eval "echo \"\${${var}:-}\"" ) 26 | 27 | [ -n "${value}" ] && return 1; 28 | if [ -f "${file}" ]; then 29 | . "${file}" 30 | else 31 | echo "ERROR: Unable to load ${file}" 32 | exit 2 33 | fi 34 | return 0; 35 | } 36 | 37 | load SSHGATE_DIRECTORY '/etc/sshgate.conf' 38 | 39 | load __SSHGATE_SETUP__ "${SSHGATE_DIRECTORY}/data/sshgate.setup" 40 | load __SSHGATE_CORE__ "${SSHGATE_DIR_CORE}/sshgate.core" 41 | 42 | # help is only needed for the CLI 43 | load __HELP_FUNC__ "${SSHGATE_DIR_CORE}/help.func" 44 | 45 | load __LIB_ASK__ "${SCRIPT_HELPER_DIRECTORY}/ask.lib.sh" 46 | load __LIB_MAIL__ "${SCRIPT_HELPER_DIRECTORY}/mail.lib.sh" 47 | load __LIB_CLI__ "${SCRIPT_HELPER_DIRECTORY}/cli.lib.sh" 48 | 49 | 50 | if [ "${SSHGATE_TEST:-}" != 'sshGateTest' ]; then 51 | # during test, don't check for user 52 | SSHKEY_USER= 53 | while true ; do 54 | [ $# -eq 0 ] && break; 55 | case $1 in 56 | -u ) shift; SSHKEY_USER="$1"; shift ;; 57 | * ) shift ;; # ignore 58 | esac 59 | done 60 | 61 | if [ -z "${SSHKEY_USER}" ]; then 62 | echo "ERROR: you have to specify a username to use sshgate CLI" 63 | echo "usage: $0 -u " 64 | exit 1 65 | fi 66 | fi # end of: if [ "${SSHGATE_TEST:-}" != 'sshGateTest' ]; then 67 | 68 | # don't want to add exec.lib.sh in dependencies :/ 69 | user_id=`id -u` 70 | [ "${user_id}" != "0" ] \ 71 | && KO "You must execute $0 with root privileges" 72 | 73 | CLI_REGISTER_HELP '/tmp/sshgate-cli-help.txt' \ 74 | SSHGATE_GET_HELP \ 75 | SSHGATE_DISPLAY_HELP \ 76 | SSHGATE_DISPLAY_HELP_FOR 77 | 78 | CLI_REGISTER_MENU 'user' 'User related commands' 79 | CLI_REGISTER_COMMAND 'user list' 'USERS_LIST' 80 | CLI_REGISTER_COMMAND 'user list ' 'USERS_LIST \1' 81 | CLI_REGISTER_COMMAND 'user add mail ' 'USER_ADD \1 \2' 82 | CLI_REGISTER_COMMAND 'user del ' 'USER_DEL \1' 83 | CLI_REGISTER_COMMAND 'user build auth_keys' 'USERS_AUTH_KEYS_BUILD' 84 | 85 | CLI_REGISTER_MENU 'user ' 86 | CLI_REGISTER_COMMAND 'user display conf' 'USER_DISPLAY_CONF \1' 87 | CLI_REGISTER_COMMAND 'user set conf ' 'USER_SET_CONF \1 \2 \3' 88 | CLI_REGISTER_COMMAND 'user del conf ' 'USER_SET_CONF \1 \2' 89 | CLI_REGISTER_COMMAND 'user list targets' 'USER_LIST_TARGETS \1' 90 | CLI_REGISTER_COMMAND 'user list usergroups' 'USER_LIST_USERGROUPS \1' 91 | CLI_REGISTER_COMMAND 'user has access [@]' 'HAS_ACCESS \1 \2' 92 | CLI_REGISTER_COMMAND 'user access info' 'USER_ACCESS_INFO \1' 93 | CLI_REGISTER_COMMAND 'user access notify' 'USER_ACCESS_NOTIFY \1' 94 | CLI_REGISTER_COMMAND 'user edit sshkey' 'USER_SSHKEY_EDIT \1' 95 | CLI_REGISTER_COMMAND 'user display sshkey' 'USER_SSHKEY_DISPLAY \1' 96 | CLI_REGISTER_COMMAND 'user update auth_keys' 'USER_AUTH_KEYS_UPDATE \1' 97 | 98 | CLI_REGISTER_MENU 'usergroup' 'Usergroup related commands' 99 | CLI_REGISTER_COMMAND 'usergroup list' 'USERGROUPS_LIST' 100 | CLI_REGISTER_COMMAND 'usergroup add ' 'USERGROUP_ADD \1' 101 | CLI_REGISTER_COMMAND 'usergroup del ' 'USERGROUP_DEL \1' 102 | 103 | CLI_REGISTER_MENU 'usergroup ' 104 | CLI_REGISTER_COMMAND 'usergroup list users' 'USERGROUP_LIST_USERS \1' 105 | CLI_REGISTER_COMMAND 'usergroup add user ' 'USERGROUP_ADD_USER \1 \2' 106 | CLI_REGISTER_COMMAND 'usergroup del user ' 'USERGROUP_DEL_USER \1 \2' 107 | CLI_REGISTER_COMMAND 'usergroup list targets' 'USERGROUP_LIST_TARGETS \1' 108 | CLI_REGISTER_COMMAND 'usergroup access info' 'USERGROUP_ACCESS_INFO \1' 109 | CLI_REGISTER_COMMAND 'usergroup access notify' 'USERGROUP_ACCESS_NOTIFY \1' 110 | 111 | CLI_REGISTER_MENU 'target' 'Target related commands' 112 | CLI_REGISTER_COMMAND 'target list' 'TARGETS_LIST' 113 | CLI_REGISTER_COMMAND 'target list ' 'TARGETS_LIST \1' 114 | CLI_REGISTER_COMMAND 'target add [@]' 'TARGET_ADD \1' 115 | CLI_REGISTER_COMMAND 'target add [@] with proxy [@]' 'TARGET_ADD \1 \2' 116 | CLI_REGISTER_COMMAND 'target add [@] via [@]' 'TARGET_ADD \1 \2' 117 | CLI_REGISTER_COMMAND 'target del ' 'TARGET_DEL \1' 118 | CLI_REGISTER_COMMAND 'target alias list' 'TARGET_LIST_ALIASES' 119 | CLI_REGISTER_COMMAND 'target alias list ' 'TARGET_LIST_ALIASES \1' 120 | 121 | CLI_REGISTER_MENU 'target ssh' "Targets ssh related commands" 122 | CLI_REGISTER_COMMAND 'target ssh test all' 'TARGET_SSH_TEST_ALL' 123 | CLI_REGISTER_COMMAND 'target ssh install all key' 'TARGET_SSHKEY_INSTALL_ALL' 124 | CLI_REGISTER_COMMAND 'target ssh edit config' 'TARGET_SSH_EDIT_CONFIG all' 125 | CLI_REGISTER_COMMAND 'target ssh display config' 'TARGET_SSH_DISPLAY_GLOBAL_CONFIG' 126 | CLI_REGISTER_COMMAND 'target ssh update known_hosts' 'TARGET_SSH_UPDATE_KNOWN_HOSTS' 127 | 128 | CLI_REGISTER_MENU 'target ' 129 | CLI_REGISTER_COMMAND 'target rename ' 'TARGET_RENAME \1 \2' 130 | CLI_REGISTER_COMMAND 'target realname' 'TARGET_REAL \1' 131 | CLI_REGISTER_COMMAND 'target add alias ' 'TARGET_ADD_ALIAS \1 \2' 132 | CLI_REGISTER_COMMAND 'target del alias ' 'TARGET_DEL_ALIAS \2' 133 | CLI_REGISTER_COMMAND 'target list alias' 'TARGET_LIST_ALIASES \1' 134 | CLI_REGISTER_COMMAND 'target display conf' 'TARGET_DISPLAY_CONF \1' 135 | CLI_REGISTER_COMMAND 'target set conf ' 'TARGET_SET_CONF \1 \2 \3' 136 | CLI_REGISTER_COMMAND 'target del conf ' 'TARGET_SET_CONF \1 \2' 137 | 138 | CLI_REGISTER_MENU 'target ssh' "Targets ssh related commands" 139 | CLI_REGISTER_COMMAND 'target ssh test' 'TARGET_SSH_TEST \1' 140 | CLI_REGISTER_COMMAND 'target ssh list logins' 'TARGET_SSH_LIST_LOGINS \1' 141 | CLI_REGISTER_COMMAND 'target ssh add login ' 'TARGET_SSH_ADD_LOGIN \1 \2' 142 | CLI_REGISTER_COMMAND 'target ssh del login ' 'TARGET_SSH_DEL_LOGIN \1 \2' 143 | CLI_REGISTER_COMMAND 'target [@] ssh edit config' 'TARGET_SSH_EDIT_CONFIG \1' 144 | CLI_REGISTER_COMMAND 'target [@] ssh display config' 'TARGET_SSH_DISPLAY_CONFIG \1' 145 | CLI_REGISTER_COMMAND 'target [@] ssh display full config' 'TARGET_SSH_DISPLAY_FULL_CONFIG \1' 146 | 147 | CLI_REGISTER_COMMAND 'target ssh display key' 'TARGET_SSHKEY_DISPLAY \1' 148 | CLI_REGISTER_COMMAND 'target ssh edit key' 'TARGET_SSHKEY_EDIT \1' 149 | CLI_REGISTER_COMMAND 'target ssh install key' 'TARGET_SSHKEY_INSTALL \1' 150 | CLI_REGISTER_COMMAND 'target ssh use default key' 'TARGET_SSHKEY_USE_DEFAULT \1' 151 | CLI_REGISTER_COMMAND 'target ssh update known_hosts' 'TARGET_SSH_UPDATE_KNOWN_HOSTS \1' 152 | 153 | CLI_REGISTER_MENU 'target [@] access' 'Targets access related commands' 154 | CLI_REGISTER_COMMAND 'target [@] access info' 'TARGET_ACCESS_INFO \1' 155 | CLI_REGISTER_COMMAND 'target [@] access list users' 'TARGET_ACCESS_LIST_USERS \1' 156 | CLI_REGISTER_COMMAND 'target [@] access add user ' 'TARGET_ACCESS_ADD_USER \1 \2' 157 | CLI_REGISTER_COMMAND 'target [@] access del user ' 'TARGET_ACCESS_DEL_USER \1 \2' 158 | CLI_REGISTER_COMMAND 'target [@] access list usergroups' 'TARGET_ACCESS_LIST_USERGROUPS \1' 159 | CLI_REGISTER_COMMAND 'target [@] access add usergroup ' 'TARGET_ACCESS_ADD_USERGROUP \1 \2' 160 | CLI_REGISTER_COMMAND 'target [@] access del usergroup ' 'TARGET_ACCESS_DEL_USERGROUP \1 \2' 161 | 162 | CLI_REGISTER_MENU 'session' 163 | CLI_REGISTER_COMMAND 'session list current' 'SESSION_DISPLAY_CONNECTED' 164 | #CLI_REGISTER_COMMAND 'session list last' 'SESSION_LIST_LAST' 165 | #CLI_REGISTER_COMMAND 'session list last ' 'SESSION_LIST_LAST \1' 166 | CLI_REGISTER_COMMAND 'session kill ' 'SESSION_KILL \1' 167 | #CLI_REGISTER_COMMAND 'session target list' 'SESSION_TARGET_LIST \1' 168 | #CLI_REGISTER_COMMAND 'session target list ' 'SESSION_TARGET_LIST \1 \2' 169 | #CLI_REGISTER_COMMAND 'session user list' 'SESSION_USER_LIST \1' 170 | #CLI_REGISTER_COMMAND 'session user list ' 'SESSION_USER_LIST \1 \2' 171 | 172 | CLI_REGISTER_COMMAND 'debug' 'set -x' 173 | 174 | 175 | # use --force when CLI is called from remote 176 | CLI_USE_READLINE --force --history-file ~/.sshgate_history 177 | CLI_SET_PROMPT "sshGate" 178 | 179 | [ ${SSHGATE_MAIL_SEND:-} = 'Y' ] && MAIL_CREATE 180 | 181 | 182 | # during test : 183 | # - don't print Wall message 184 | # - don't run the CLI (we will launch it manually) 185 | # - don't send mail 186 | if [ "${SSHGATE_TEST:-}" != 'sshGateTest' ]; then 187 | MSG "sshGate administration Interface" 188 | MSG "By Patrick Guiran " 189 | BR 190 | MSG "Use 'help' command to list all available commands" 191 | BR 192 | 193 | CLI_RUN 194 | 195 | [ ${SSHGATE_MAIL_SEND:-} = 'Y' ] \ 196 | && MAIL_SEND "${SSHGATE_MAIL_SUBJECT} (${SSHKEY_USER})" "${SSHGATE_MAIL_TO}" 197 | [ $? -eq 2 ] && NOTICE "No modification noticed. Repport e-mail will not be sent" 198 | fi 199 | 200 | __SSHGATE_CLI__='Loaded' # mainly for tests 201 | -------------------------------------------------------------------------------- /bin/core/record.func: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright (c) 2010 Linagora 3 | # Patrick Guiran 4 | # http://github.com/Tauop/sshGate 5 | # 6 | # sshGate is free software, you can redistribute it and/or modify 7 | # it under the terms of the GNU General Public License as 8 | # published by the Free Software Foundation; either version 2 of 9 | # the License, or (at your option) any later version. 10 | # 11 | # sshGate is distributed in the hope that it will be useful, 12 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | # GNU General Public License for more details. 15 | # 16 | # You should have received a copy of the GNU Lesser General Public License 17 | # along with this program. If not, see . 18 | # 19 | # README --------------------------------------------------------------------- 20 | # 21 | # Collection of all targets sessions/logs related functions 22 | # 23 | # ---------------------------------------------------------------------------- 24 | 25 | if [ "${__SSHGATE_CORE__}" != 'Loaded' ]; then 26 | echo "ERROR: Only sshgate.core can load user.func."; exit 1; 27 | fi 28 | 29 | if [ "${__RECORD_FUNC__:-}" != 'Loaded' ]; then 30 | __RECORD_FUNC__='Loaded' 31 | 32 | # usage: private_TARGET_SESSION_GET_LOG_FILE 33 | # desc: echo-return the target global log file 34 | # note: create the target main directory in ${SSHGATGE_DIR_LOG} if needed 35 | # note: as it's a private methods, we don't print any error 36 | private_SESSION_TARGET_GET_LOG_FILE () { 37 | local target= item= 38 | if [ $# -ne 1 ]; then 39 | echo ''; return 1; 40 | fi 41 | 42 | target=$( TARGET_REAL "$1" ) 43 | if [ -z "${target}" ]; then 44 | echo ''; return 1; 45 | fi 46 | 47 | item="${SSHGATE_DIR_LOGS_TARGETS}/${target}" 48 | if [ ! -d "${item}/" ]; then 49 | mkdir -p "${item}/" 50 | chown -R "${SSHGATE_GATE_ACCOUNT}" "${item}/" 51 | fi 52 | 53 | item="${item}/global.log" 54 | touch "${item}" 55 | chown "${SSHGATE_GATE_ACCOUNT}" "${item}" 56 | chmod a=r,u+w "${item}" 57 | 58 | echo "${item}" 59 | return 0; 60 | } 61 | 62 | # usage: USER_SESSION_GET_LOG_FILE 63 | # desc: echo-return the user log file 64 | # note: create the log file if needed 65 | # note: as it's a private method, we don't print any error 66 | private_SESSION_USER_GET_LOG_FILE () { 67 | local user= item= 68 | 69 | if [ $# -ne 1 ]; then 70 | echo ''; return 1; 71 | fi 72 | 73 | user="${1:-}" 74 | if [ -z "${user}" -o ! -f "${SSHGATE_DIR_USERS}/${user}" ]; then 75 | echo ''; return 1; 76 | fi 77 | 78 | item="${SSHGATE_DIR_LOGS_USERS}/${user}.log" 79 | touch "${item}" 80 | chown "${SSHGATE_GATE_ACCOUNT}" "${item}" 81 | chmod a=r,u+w "${item}" 82 | echo "${item}" 83 | return 0; 84 | } 85 | 86 | # -------------------------------------------------------------------------- 87 | 88 | # usage: private_SESSION_STATE_CLEAN 89 | # desc: clean current_session.log file, by removing no-existing process (pid) 90 | private_SESSION_STATE_CLEAN () { 91 | local session_file= pid= rest= tmp_file= old_IFS= 92 | 93 | session_file="${SSHGATE_LOGS_CURRENT_SESSION_FILE}" 94 | tmp_file="/tmp/file.$(RANDOM)" 95 | 96 | [ ! -w "${session_file}" ] && return 1 97 | 98 | MUTEX_GET "${session_file}" 99 | cp "${session_file}" "${tmp_file}" 100 | old_IFS="${IFS}" 101 | IFS=':'; while read pid rest ; do 102 | ps -p "${pid}" >/dev/null 2>/dev/null && printf "%s:%s\n" "${pid}" "${rest}" 103 | done < "${tmp_file}" > "${session_file}" 104 | IFS="${old_IFS}" 105 | MUTEX_RELEASE "${session_file}" 106 | 107 | rm -f "${tmp_file}" 108 | 109 | return 0 110 | } 111 | 112 | # usage: private_SESSION_CURRENT_ADD 113 | # desc: add session state information 114 | private_SESSION_STATE_ADD () { 115 | local log_msg= session_file= 116 | 117 | session_file="${SSHGATE_LOGS_CURRENT_SESSION_FILE}" 118 | # format = :::::<...info ..> 119 | log_msg="${2:-}:${1:-}:${3:-}:${4:-}:${5:-}" 120 | shift 5 121 | log_msg="${log_msg}:$*" 122 | 123 | private_SESSION_STATE_CLEAN 124 | 125 | MUTEX_GET "${session_file}" 126 | echo "${log_msg}" >> "${session_file}" 127 | MUTEX_RELEASE "${session_file}" 128 | 129 | return 0; 130 | } 131 | 132 | # usage: private_SESSION_STATE_REMOVE 133 | # desc: remove session state information 134 | private_SESSION_STATE_REMOVE () { 135 | local session_file= nb= 136 | if [ $# -ne 1 ]; then 137 | BAD_ARGUMENTS ; return 1; 138 | fi 139 | 140 | session_file="${SSHGATE_LOGS_CURRENT_SESSION_FILE}" 141 | 142 | private_SESSION_STATE_CLEAN 143 | 144 | MUTEX_GET "${session_file}" 145 | if [ -w "${session_file}" ]; then 146 | grep -v "^$1:" < "${session_file}" > "${session_file}.tmp" 147 | mv "${session_file}.tmp" "${session_file}" 148 | nb=$( wc -l < "${session_file}" | cut -d' ' -f1 ) 149 | [ "${nb}" = '0' ] && rm -f "${session_file}" 150 | fi 151 | MUTEX_RELEASE "${session_file}" 152 | 153 | return 0; 154 | } 155 | 156 | # -------------------------------------------------------------------------- 157 | 158 | # usage: private_SESSION_WRITE_EVENT 159 | # desc: write an event into target logs and user logs 160 | private_SESSION_WRITE_EVENT () { 161 | local log_msg= log_file= target= user= 162 | 163 | user="${4:-}"; target="${5:-}" 164 | log_msg="${2:-}:${1:-}:${3:-}:${4:-}:${5:-}" 165 | shift 5; 166 | log_msg="${log_msg}:$*" 167 | 168 | # in target global session file 169 | log_file=$( private_SESSION_TARGET_GET_LOG_FILE "${target}" ) 170 | if [ -n "${log_file}" ]; then 171 | MUTEX_GET "${log_file}" 172 | echo "${log_msg}" >> "${log_file}" 173 | MUTEX_RELEASE "${log_file}" 174 | fi 175 | 176 | # in user global session file 177 | log_file=$( private_SESSION_USER_GET_LOG_FILE "${user}" ) 178 | if [ -n "${log_file}" ]; then 179 | MUTEX_GET "${log_file}" 180 | echo "${log_msg}" >> "${log_file}" 181 | MUTEX_RELEASE "${log_file}" 182 | fi 183 | 184 | # in global session log file 185 | log_file="${SSHGATE_GLOBAL_SESSION_LOG_FILE}" 186 | if [ -n "${log_file}" ]; then 187 | MUTEX_GET "${log_file}" 188 | # :::: 189 | echo "${log_msg}" >> "${log_file}" 190 | MUTEX_RELEASE "${log_file}" 191 | fi 192 | 193 | return 0; 194 | } 195 | 196 | # usage: SESSION_START [ .... ] 197 | # desc: Log the connection start event into target logs and user logs 198 | # note: can be 'ssh' or 'scp', or whatever you want 199 | SESSION_START () { 200 | private_SESSION_WRITE_EVENT 'START' $@ ; 201 | private_SESSION_STATE_ADD $@ 202 | } 203 | 204 | # usage: TARGET_SESSION_END 205 | # desc: Log the connection end event into target global file 206 | SESSION_END () { 207 | private_SESSION_WRITE_EVENT 'END' $@ ; 208 | private_SESSION_STATE_REMOVE "${2:-}" 209 | } 210 | 211 | # -------------------------------------------------------------------------- 212 | 213 | # usage: SESSION_GET_TARGET_RECORD_FILE 214 | # desc: echo-return a random-generated target session log file path 215 | # note: we don't create/touch the file 216 | SESSION_TARGET_GET_RECORD_FILE () { 217 | local timestamp= user= target= f= 218 | if [ $# -ne 3 ]; then 219 | BAD_ARGUMENTS ; return 1; 220 | fi 221 | 222 | timestamp="$1"; user="$2"; target="$3" 223 | target=$( TARGET_REAL "${target}" ) 224 | if [ -z "${target}" -o -z "${user}" ]; then 225 | echo ''; return 1; 226 | fi 227 | 228 | f="${SSHGATE_DIR_LOGS_TARGETS}/${target}/${timestamp}.${user}.$$" 229 | echo "$f" 230 | return 0; 231 | } 232 | 233 | # -------------------------------------------------------------------------- 234 | 235 | # usage: SESSION_DISPLAY_CONNECTED 236 | # desc: echo-return the list of connected sessions 237 | SESSION_DISPLAY_CONNECTED () { 238 | local session_file= pid= time= user= target= old_IFS= 239 | 240 | session_file="${SSHGATE_LOGS_CURRENT_SESSION_FILE}" 241 | 242 | if [ -f "${session_file}" ]; then 243 | private_SESSION_STATE_CLEAN 244 | 245 | MUTEX_GET "${session_file}" 246 | old_IFS="${IFS}" 247 | IFS=':'; while read pid time user target type info; do 248 | printf "[%5s] %s --(%s)--> %s (%s%s)\n" "${pid}" "${user}" "${type}" "${target}" "$( date -d "1970-01-01 UTC ${time} seconds" +'%Y-%m-%d %T %z' )" "${info:+ - ${info}}" 249 | done < "${session_file}" 250 | IFS="${old_IFS}" 251 | MUTEX_RELEASE "${session_file}" 252 | else 253 | echo "No user connected" 254 | fi 255 | } 256 | 257 | # usage: SESSION_TARGET_LIST 258 | # desc: Display all sessions logs of the 259 | SESSION_TARGET_LIST () { 260 | local target= 261 | 262 | if [ $# -ne 1 ]; then 263 | BAD_ARGUMENTS ; return 1; 264 | fi 265 | 266 | target=$( TARGET_REAL "$1" ) 267 | if [ -z "${target}" ]; then 268 | ERROR "Target '$1' doesn't exist"; return 1; 269 | fi 270 | 271 | ls -1 "${SSHGATE_DIR_LOGS_TARGETS}/${target}" 272 | 273 | return 0; 274 | } 275 | 276 | # usage: SESSION_LIST_LAST 277 | # desc: Display number-last closed session 278 | SESSION_LIST_LAST () { 279 | local nb= 280 | 281 | if [ $# -ne 0 -a $# -ne 1 ]; then 282 | BAD_ARGUMENTS ; return 1; 283 | fi 284 | 285 | [ $# -eq 1 ] && nb=$? 286 | if ! test ${nb} -eq ${nb} 2>/dev/null ; then 287 | ERROR "First argument must be a number"; return 1; 288 | fi 289 | 290 | echo 'Not Yet implemented :-(' 291 | return 0 292 | } 293 | 294 | # usage: SESSION_KILL 295 | # desc: Kill a sshGate session 296 | SESSION_KILL () { 297 | local pid= session_file= tmp= 298 | if [ $# -ne 1 ]; then 299 | BAD_ARGUMENTS; return 1; 300 | fi 301 | 302 | pid="$1" 303 | session_file="${SSHGATE_LOGS_CURRENT_SESSION_FILE}" 304 | 305 | if [ -w "${session_file}" ]; then 306 | grep "^${pid}:" < "${session_file}" >/dev/null 2>/dev/null 307 | if [ $? -eq 0 ]; then 308 | # get the process tty/pts 309 | tmp=$( ps -p "${pid}" -o tty ) 310 | if [ $? -ne 0 ]; then 311 | ERROR "No such process ${pid}." 312 | return 1 313 | fi 314 | # in worst case, it will kill the ssh process which launch sshgate-bridge 315 | kill -HUP $( ps -t `echo "${tmp}" | tail -n 1` -o pid | sort -n | tail -n 1 ) >/dev/null 2>/dev/null 316 | [ $? -ne 0 ] \ 317 | && ERROR "Can't kill or no such session ${pid}." \ 318 | || MESSAGE "Session ${pid} killed." 319 | private_SESSION_STATE_REMOVE "${pid}" 320 | fi 321 | else 322 | ERROR "No active session" 323 | fi 324 | 325 | return 0 326 | } 327 | 328 | fi # end of: if [ "${__RECORD_FUNC__:-}" != 'Loaded' ]; then 329 | -------------------------------------------------------------------------------- /bin/core/target-access.func: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright (c) 2010 Linagora 3 | # Patrick Guiran 4 | # http://github.com/Tauop/sshGate 5 | # 6 | # sshGate is free software, you can redistribute it and/or modify 7 | # it under the terms of the GNU General Public License as 8 | # published by the Free Software Foundation; either version 2 of 9 | # the License, or (at your option) any later version. 10 | # 11 | # sshGate is distributed in the hope that it will be useful, 12 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | # GNU General Public License for more details. 15 | # 16 | # You should have received a copy of the GNU Lesser General Public License 17 | # along with this program. If not, see . 18 | # 19 | # README --------------------------------------------------------------------- 20 | # 21 | # Collection of all targets access related functions 22 | # 23 | # ---------------------------------------------------------------------------- 24 | 25 | if [ "${__SSHGATE_CORE__}" != 'Loaded' ]; then 26 | echo "ERROR: Only sshgate.core can load user.func."; exit 1; 27 | fi 28 | 29 | if [ "${__TARGET_ACCESS_FUNC__:-}" != 'Loaded' ]; then 30 | __TARGET_ACCESS_FUNC__='Loaded' 31 | 32 | # usage: TARGET_ACCESS_INFO 33 | # desc: List all user who has access to the target, and how 34 | TARGET_ACCESS_INFO () { 35 | local target= login= targetgroup_list= users_list= 36 | if [ $# -ne 1 ]; then 37 | BAD_ARGUMENTS ; return 1; 38 | fi 39 | 40 | target=$( TARGET_REAL "$1" ) 41 | if [ -z "${target}" ]; then 42 | ERROR "Target host '${target}' doesn't exist" ; return 1; 43 | fi 44 | 45 | # direct access 46 | for login in $( TARGET_SSH_LIST_LOGINS "${target}" ); do 47 | users_list=$( cat "${SSHGATE_DIR_TARGETS}/${target}/${SSHGATE_TARGETS_USER_ACCESS_FILENAME}.${login}" | sort -u ) 48 | if [ -n "${users_list}" ]; then 49 | echo -n " ${users_list}" | tr $'\n' ',' 50 | echo " ---> ${login}@${target}" 51 | fi 52 | done 53 | 54 | # access through usergroup 55 | for login in $( TARGET_SSH_LIST_LOGINS "${target}" ); do 56 | for usergroup in $( TARGET_ACCESS_LIST_USERGROUPS "${target}" "${login}" ); do 57 | users_list=$( USERGROUP_LIST_USERS "${usergroup}" ) 58 | if [ -n "${users_list}" ]; then 59 | echo -n " ${users_list}" | tr $'\n' ',' 60 | echo " --- usergroup(${usergroup}) ---> ${login}@${target}" 61 | fi 62 | done 63 | done # end of : for login in $( TARGET_SSH_LIST_LOGINS "${target}" ); do 64 | return 0; 65 | } 66 | 67 | # usage: TARGET_ACCESS_LIST_USERS [@] 68 | # usage: TARGET_ACCESS_LIST_USERS 69 | # desc: List users who have access to the target host 70 | # note: if no is given, use ${SSHGATE_TARGETS_DEFAULT_SSH_LOGIN} 71 | TARGET_ACCESS_LIST_USERS () { 72 | local target= login= files= 73 | if [ $# -ne 1 -a $# -ne 2 ]; then 74 | BAD_ARGUMENTS ; return 1; 75 | fi 76 | 77 | if [ $# -eq 1 ]; then 78 | target=$( GET_HOST "$1" ) 79 | login=$( GET_LOGIN "$1" ) 80 | else 81 | target="$1"; login="$2" 82 | fi 83 | 84 | target=$( TARGET_REAL "${target}" ) 85 | if [ -z "${target}" ]; then 86 | ERROR "Target host '${target}' doesn't exist" ; return 1; 87 | fi 88 | 89 | TARGET_SSH_LIST_LOGINS "${target}" | grep "^${login}$" >/dev/null 90 | if [ $? -ne 0 ]; then 91 | ERROR "Login '${login}' doesn't exist on target '${target}'"; return 1; 92 | fi 93 | 94 | files="${SSHGATE_DIR_TARGETS}/${target}/${SSHGATE_TARGETS_USER_ACCESS_FILENAME}.${login}" 95 | 96 | # through groups : target -> usergroup -> users 97 | for usergroup in $( cat "${SSHGATE_DIR_TARGETS}/${target}/${SSHGATE_TARGETS_USERGROUP_ACCESS_FILENAME}.${login}" ); do 98 | files="${files} ${SSHGATE_DIR_USERS_GROUPS}/${usergroup}" 99 | done 100 | 101 | cat ${files} | sort -u 102 | return 0; 103 | } 104 | 105 | # usage: TARGET_ACCESS_LIST_USERS 106 | # desc: List users who have access to the target host for each ssh login 107 | TARGET_ACCESS_LIST_ALL_USERS () { 108 | local target= login= 109 | if [ $# -ne 1 ]; then 110 | BAD_ARGUMENTS; return 1; 111 | fi 112 | 113 | target=$( TARGET_REAL "$1" ) 114 | if [ -z "${target}" ]; then 115 | ERROR "Target host '${target}' doesn't exist"; return 1; 116 | fi 117 | 118 | for login in $( TARGET_SSH_LIST_LOGINS "${target}" ); do 119 | echo "= ${login}@${target} =" 120 | TARGET_ACCESS_LIST_USERS "${target}" "${login}" 121 | done 122 | return 0; 123 | } 124 | 125 | # usage: TARGET_ACCESS_ADD_USER [@] 126 | # usage: TARGET_ACCESS_ADD_USER 127 | # desc: Give to the user access to target host 128 | # note: if no is given, use ${SSHGATE_TARGETS_DEFAULT_SSH_LOGIN} 129 | TARGET_ACCESS_ADD_USER () { 130 | local target= login= user= 131 | if [ $# -ne 2 -a $# -ne 3 ]; then 132 | BAD_ARGUMENTS ; return 1; 133 | fi 134 | 135 | if [ $# -eq 2 ]; then 136 | target=$( GET_HOST "$1" ) 137 | login=$( GET_LOGIN "$1" ) 138 | user="$2" 139 | else 140 | target="$1"; login="$2"; user="$3" 141 | fi 142 | 143 | if [ -z "${user}" ]; then 144 | BAD_ARGUMENTS ; return 1; 145 | fi 146 | 147 | target=$( TARGET_REAL "${target}" ) 148 | if [ -z "${target}" ]; then 149 | ERROR "Target host '${target}' doesn't exist" ; return 1; 150 | fi 151 | if [ ! -f "${SSHGATE_DIR_USERS}/${user}" ]; then 152 | ERROR "User '${user}' doesn't exist" ; return 1; 153 | fi 154 | 155 | TARGET_SSH_LIST_LOGINS "${target}" | grep "^${login}$" >/dev/null 156 | if [ $? -ne 0 ]; then 157 | ERROR "Login '${login}' doesn't exist on '${target}'"; return 1; 158 | fi 159 | 160 | private_ACL_FILE_ADD "${user}" "${SSHGATE_DIR_TARGETS}/${target}/${SSHGATE_TARGETS_USER_ACCESS_FILENAME}.${login}" 161 | private_MAIL_APPEND "User ${user} access to Target ${login}@${target} granted" 162 | 163 | return 0; 164 | } 165 | 166 | # usage: TARGET_ACCESS_DEL_USER [@] 167 | # usage: TARGET_ACCESS_DEL_USER 168 | # desc: Revoke user access to target host 169 | # note: if no is given, use ${SSHGATE_TARGETS_DEFAULT_SSH_LOGIN} 170 | TARGET_ACCESS_DEL_USER () { 171 | local target= login= user= access_file= 172 | if [ $# -ne 2 -a $# -ne 3 ]; then 173 | BAD_ARGUMENTS ; return 1 174 | fi 175 | 176 | if [ $# -eq 2 ]; then 177 | target=$( GET_HOST "$1" ) 178 | login=$( GET_LOGIN "$1" ) 179 | user="$2" 180 | else 181 | target="$1"; login="$2"; user="$3" 182 | fi 183 | 184 | if [ -z "${user}" ]; then 185 | BAD_ARGUMENTS ; return 1; 186 | fi 187 | target=$( TARGET_REAL "${target}" ) 188 | if [ -z "${target}" ]; then 189 | ERROR "Target host '${target}' doesn't exist" ; return 1; 190 | fi 191 | if [ ! -f "${SSHGATE_DIR_USERS}/${user}" ]; then 192 | ERROR "User '${user}' doesn't exist" ; return 1; 193 | fi 194 | 195 | TARGET_SSH_LIST_LOGINS "${target}" | grep "^${login}$" >/dev/null 196 | if [ $? -ne 0 ]; then 197 | ERROR "Login '${login}' doesn't exist on target '${target}'"; return 1; 198 | fi 199 | 200 | private_ACL_FILE_DEL "${user}" "${SSHGATE_DIR_TARGETS}/${target}/${SSHGATE_TARGETS_USER_ACCESS_FILENAME}.${login}" 201 | private_MAIL_APPEND "User ${user} access to Target ${login}@${target} revoked" 202 | 203 | return 0; 204 | } 205 | 206 | # usage: TARGET_ACCESS_LIST_USERGROUPS [@] 207 | # usage: TARGET_ACCESS_LIST_USERGROUPS 208 | # desc: List all groups who can access to @ 209 | TARGET_ACCESS_LIST_USERGROUPS () { 210 | local target= login= 211 | if [ $# -ne 1 -a $# -ne 2 ]; then 212 | BAD_ARGUMENTS ; return 1; 213 | fi 214 | 215 | if [ $# -eq 1 ]; then 216 | target=$( GET_HOST "$1" ) 217 | login=$( GET_LOGIN "$1" ) 218 | else 219 | target="$1"; login="$2" 220 | fi 221 | 222 | target=$( TARGET_REAL "${target}" ) 223 | if [ -z "${target}" ]; then 224 | ERROR "Target host '${target}' doesn't exist" ; return 1; 225 | fi 226 | 227 | TARGET_SSH_LIST_LOGINS "${target}" | grep "^${login}$" >/dev/null 228 | if [ $? -ne 0 ]; then 229 | ERROR "Login '${login}' doesn't exist on target '${target}'"; return 1; 230 | fi 231 | 232 | cat "${SSHGATE_DIR_TARGETS}/${target}/${SSHGATE_TARGETS_USERGROUP_ACCESS_FILENAME}.${login}" | sort -u 233 | return 0; 234 | } 235 | 236 | # usage: TARGET_ACCESS_LIST_ALL_USERGROUPS 237 | # desc: List all groups who can access to the target host, for each ssh login 238 | TARGET_ACCESS_LIST_ALL_USERGROUPS () { 239 | local target= login= 240 | 241 | if [ $# -ne 1 ]; then 242 | BAD_ARGUMENTS; return 1; 243 | fi 244 | 245 | target=$( TARGET_REAL "$1" ) 246 | if [ -z "${target}" ]; then 247 | ERROR "Target host '${target}' doesn't exist"; return 1; 248 | fi 249 | 250 | for login in $( TARGET_SSH_LIST_LOGINS "${target}" ); do 251 | echo "= ${login}@${target} =" 252 | TARGET_ACCESS_LIST_USERGROUPS "${target}" "${login}" 253 | done 254 | } 255 | 256 | # usage: TARGET_ACCESS_ADD_USERGROUP [@] 257 | # usage: TARGET_ACCESS_ADD_USERGROUP 258 | # desc: Give to a usergroup access to a target host 259 | # note: if is not given, use ${SSHGATE_TARGETS_DEFAULT_SSH_LOGIN} 260 | TARGET_ACCESS_ADD_USERGROUP () { 261 | local target= login= usergroup= 262 | if [ $# -ne 2 -a $# -ne 3 ]; then 263 | BAD_ARGUMENTS ; return 1; 264 | fi 265 | 266 | if [ $# -eq 2 ]; then 267 | target=$( GET_HOST "$1" ) 268 | login=$( GET_LOGIN "$1" ) 269 | usergroup="$2" 270 | else 271 | target="$1"; login="$2"; usergroup="$3" 272 | fi 273 | 274 | if [ -z "${usergroup}" ]; then 275 | BAD_ARGUMENTS ; return 1; 276 | fi 277 | 278 | target=$( TARGET_REAL "${target}" ) 279 | if [ -z "${target}" ]; then 280 | ERROR "Target host '${target}' doesn't exist" ; return 1; 281 | fi 282 | if [ ! -f "${SSHGATE_DIR_USERS_GROUPS}/${usergroup}" ]; then 283 | ERROR "User group '${usergroup}' doesn't exist" ; return 1; 284 | fi 285 | 286 | private_ACL_FILE_ADD "${usergroup}" "${SSHGATE_DIR_TARGETS}/${target}/${SSHGATE_TARGETS_USERGROUP_ACCESS_FILENAME}.${login}" 287 | private_MAIL_APPEND "User Group ${usergroup} access to Target ${login}@${target} granted" 288 | 289 | return 0; 290 | } 291 | 292 | # usage: TARGET_ACCESS_DEL_USERGROUP [@] 293 | # usage: TARGET_ACCESS_DEL_USERGROUP 294 | # desc: Revoke usergroup access to a target host 295 | # note: if is not given, use ${SSHGATE_TARGETS_DEFAULT_SSH_LOGIN} 296 | TARGET_ACCESS_DEL_USERGROUP () { 297 | local target= login= usergroup= 298 | if [ $# -ne 2 -a $# -ne 3 ]; then 299 | BAD_ARGUMENTS ; return 1 300 | fi 301 | 302 | if [ $# -eq 2 ]; then 303 | target=$( GET_HOST "$1" ) 304 | login=$( GET_LOGIN "$1" ) 305 | usergroup="$2" 306 | else 307 | target="$1"; login="$2"; usergroup="$3" 308 | fi 309 | 310 | if [ -z "${usergroup}" ]; then 311 | BAD_ARGUMENTS ; return 1; 312 | fi 313 | 314 | target=$( TARGET_REAL "${target}" ) 315 | if [ -z "${target}" ]; then 316 | ERROR "Target host '${target}' doesn't exist" ; return 1; 317 | fi 318 | if [ ! -f "${SSHGATE_DIR_USERS_GROUPS}/${usergroup}" ]; then 319 | ERROR "User group '${usergroup}' doesn't exist" ; return 1; 320 | fi 321 | 322 | private_ACL_FILE_DEL "${usergroup}" "${SSHGATE_DIR_TARGETS}/${target}/${SSHGATE_TARGETS_USERGROUP_ACCESS_FILENAME}.${login}" 323 | private_MAIL_APPEND "User Group ${usergroup} access to Target ${login}@${target} revoked" 324 | 325 | return 0; 326 | } 327 | 328 | fi # end of: if [ "${__TARGET_ACCESS_FUNC__:-}" != 'Loaded' ]; then 329 | -------------------------------------------------------------------------------- /bin/core/target.func: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright (c) 2010 Linagora 3 | # Patrick Guiran 4 | # http://github.com/Tauop/sshGate 5 | # 6 | # sshGate is free software, you can redistribute it and/or modify 7 | # it under the terms of the GNU General Public License as 8 | # published by the Free Software Foundation; either version 2 of 9 | # the License, or (at your option) any later version. 10 | # 11 | # sshGate is distributed in the hope that it will be useful, 12 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | # GNU General Public License for more details. 15 | # 16 | # You should have received a copy of the GNU Lesser General Public License 17 | # along with this program. If not, see . 18 | # 19 | # README --------------------------------------------------------------------- 20 | # 21 | # Collection of all targets related functions 22 | # 23 | # ---------------------------------------------------------------------------- 24 | 25 | if [ "${__SSHGATE_CORE__}" != 'Loaded' ]; then 26 | echo "ERROR: Only sshgate.core can load user.func."; exit 1; 27 | fi 28 | 29 | if [ "${__TARGET_FUNC__:-}" != 'Loaded' ]; then 30 | __TARGET_FUNC__='Loaded' 31 | 32 | # usage: TARGETS_LIST 33 | # desc: list all targets, whose name match if given 34 | TARGETS_LIST () { 35 | local res= find_opt= 36 | [ $# -eq 1 ] && find_opt="-iname '$1'" 37 | 38 | res=$( eval "find '${SSHGATE_DIR_TARGETS}' -mindepth 1 -type d ${find_opt} -printf '%P\n'" ) 39 | echo "${res}" | sort -u 40 | return 0; 41 | } 42 | 43 | # usage: TARGET_ADD [@] [ [@] ] 44 | # desc: add a target host 45 | # note: it will add the ${SSHGATE_TARGETS_DEFAULT_SSH_LOGIN} login to target 46 | # note: it will try to install public sshket to the target authorized_keys2 47 | # note: if no is given, use ${SSHGATE_TARGETS_DEFAULT_SSH_LOGIN} 48 | # important: need to be root to be able to chown ssh priv key 49 | TARGET_ADD () { 50 | local target= privsshkey= tmp_file= proxy= proxy_login= reply= 51 | if [ $# -lt 1 -a $# -gt 3 ]; then 52 | BAD_ARGUMENTS ; return 1; 53 | fi 54 | 55 | target=$( GET_HOST "$1" ) 56 | login=$( GET_LOGIN "$1" ) 57 | if [ -z "${target}" ]; then 58 | BAD_ARGUMENTS ; return 1; 59 | fi 60 | 61 | if [ -d "${SSHGATE_DIR_TARGETS}/${target}" \ 62 | -o -L "${SSHGATE_DIR_TARGETS}/${target}" ]; then 63 | ERROR "Target or Alias '${target}' already exist"; return 1; 64 | fi 65 | 66 | if [ $# -eq 2 ]; then 67 | proxy=$( GET_HOST "$2" ) 68 | proxy_login=$( GET_LOGIN "$2" ) 69 | proxy=$( TARGET_REAL "${proxy}" ) 70 | if [ -z "${proxy}" ]; then 71 | ERROR "Proxy target host '${proxy}' doesn't exist"; return 1; 72 | fi 73 | fi 74 | 75 | 76 | # check that the host exists (DNS/IP) 77 | if [ -z "${proxy}" ]; then 78 | ping -c 1 "${target}" >/dev/null 2>/dev/null 79 | else 80 | TARGET_SSH_RUN_COMMAND "${login}@${proxy}" "ping -c 1 '${target}' >/dev/null 2>/dev/null" 81 | fi 82 | if [ $? -ne 0 ]; then 83 | echo "Warning: Unable to ping ${target} !"; 84 | ASK --yesno reply 'Continue [Y] ? ' 85 | if [ "${var}" = 'N' ]; then 86 | ERROR "Adding '${target}' stoped"; return 1; 87 | fi 88 | fi 89 | 90 | # create the target now 91 | mkdir -p "${SSHGATE_DIR_TARGETS}/${target}" 2>/dev/null 92 | if [ $? -ne 0 ]; then 93 | ERROR "Can't create target data"; return 1; 94 | fi 95 | 96 | target_add_rollback () { 97 | ERROR "Can't create target '${target}'"; 98 | TARGET_DEL "${target}" 99 | } 100 | 101 | if [ -n "${proxy}" ]; then 102 | TARGET_SET_CONF "${target}" SSH_PROXY "${proxy_login}@${proxy}" 103 | if [ $? -ne 0 ]; then 104 | target_add_rollback; return 1; 105 | fi 106 | fi 107 | 108 | TARGET_SSHKEY_EDIT "${target}" 109 | if [ $? -ne 0 ]; then 110 | target_add_rollback; return 1; 111 | fi 112 | 113 | TARGET_SSH_ADD_LOGIN "${target}" "${login}" 114 | if [ $? -ne 0 ]; then 115 | target_add_rollback; return 1; 116 | fi 117 | 118 | private_TARGET_KNOWN_HOSTS_ADD "${target}" 119 | if [ $? -ne 0 ]; then 120 | echo "NOTICE: Can't add identity of host in know_hosts file. Use 'target ${target}' to add it manually" 121 | echo "NOTICE: Public ssh key of '${target}' can't be installed on '${login}@${target}'. Install it manually" 122 | else 123 | TARGET_SSHKEY_INSTALL "${target}" "${login}" 124 | fi 125 | 126 | private_MAIL_APPEND "Target ${login}@${target} added" 127 | 128 | chown -R "${SSHGATE_GATE_ACCOUNT}" "${SSHGATE_DIR_TARGETS}/${target}" 129 | 130 | return 0; 131 | } 132 | 133 | # usage: TARGET_DEL 134 | # desc: Delete a target host 135 | TARGET_DEL () { 136 | local target= 137 | if [ $# -ne 1 ]; then 138 | BAD_ARGUMENTS ; return 1; 139 | fi 140 | 141 | target=$( TARGET_REAL "$1" ) 142 | if [ -z "${target}" ]; then 143 | ERROR "Target host '${target}' doesn't exist"; return 1 144 | fi 145 | 146 | private_TARGET_KNOWN_HOSTS_DEL "${target}" 147 | 148 | for alias in $( TARGET_LIST_ALIASES "${target}" ); do 149 | rm -f "${SSHGATE_DIR_TARGETS}/${alias}" 150 | done 151 | 152 | rm -rf "${SSHGATE_DIR_TARGETS}/${target}" 153 | 154 | private_MAIL_APPEND "Target ${target} removed" 155 | 156 | return 0; 157 | } 158 | 159 | # usage: TARGET_RENAME 160 | # desc: Rename a target host and create an alias with the old target name 161 | TARGET_RENAME () { 162 | local target= target_port= new_name= new_target= 163 | if [ $# -ne 2 ]; then 164 | BAD_ARGUMENTS ; return 1; 165 | fi 166 | target=$( TARGET_REAL "$1" ); new_name=$( echo "$2" | tr '[:upper:]' '[:lower:]' ); new_target=$( TARGET_REAL "${new_name}" ) 167 | if [ -z "${target}" ]; then 168 | ERROR "Target host '${target}' doesn't exist"; return 1; 169 | fi 170 | if [ "${target}" != "$1" ]; then 171 | ERROR "Target name '$1' is an alias of '${target}'"; return 1; 172 | fi 173 | if [ -n "${new_target}" ]; then 174 | ERROR "Target name '${new_name}' already used"; return 1; 175 | fi 176 | 177 | mv "${SSHGATE_DIR_TARGETS}/${target}" "${SSHGATE_DIR_TARGETS}/${new_name}" 178 | if [ -d "${SSHGATE_DIR_LOGS_TARGETS}/${target}/" ]; then 179 | mv "${SSHGATE_DIR_LOGS_TARGETS}/${target}" "${SSHGATE_DIR_LOGS_TARGETS}/${new_name}" 180 | fi 181 | echo "Target renamed : ${target} -> ${new_name}" 182 | 183 | TARGET_ADD_ALIAS "${new_name}" "${target}" 184 | echo "Target alias '${target}' created" 185 | 186 | private_TARGET_KNOWN_HOSTS_ADD "${new_name}" 187 | private_MAIL_APPEND "Target ${target} renamed to ${new_name}" 188 | 189 | return 0; 190 | } 191 | 192 | # usage: TARGET_DISPLAY_CONF 193 | # desc: Display the configuration file of the target 194 | TARGET_DISPLAY_CONF () { 195 | local target= file= 196 | if [ $# -ne 1 ]; then 197 | BAD_ARGUMENTS; return 1; 198 | fi 199 | 200 | target=$( TARGET_REAL "$1" ) 201 | if [ -z "${target}" ]; then 202 | ERROR "Target host '${target}' doesn't exist" ; return 1; 203 | fi 204 | 205 | file="${SSHGATE_DIR_TARGETS}/${target}/properties" 206 | if [ ! -f "${file}" ]; then 207 | NOTICE "Target host '${target}' has no configuration file" 208 | else 209 | cat "${file}" 210 | fi 211 | return 0 212 | } 213 | 214 | # usage: TARGET_SET_CONF [ ] 215 | # desc: Set a variable/value pair into the target configuration file 216 | # note: if no is given, the is removed from the 217 | # configuration file of the 218 | TARGET_SET_CONF () { 219 | local target= var= value= file= 220 | if [ $# -lt 2 -o $# -gt 3 ]; then 221 | BAD_ARGUMENTS; return 1; 222 | fi 223 | 224 | target="$1"; var="$2" 225 | [ $# -eq 3 ] && value="$3" 226 | 227 | if [ -z "${target}" -o -z "${var}" ]; then 228 | BAD_ARGUMENTS; return 1; 229 | fi 230 | 231 | target=$( TARGET_REAL "${target}" ) 232 | if [ -z "${target}" ]; then 233 | ERROR "Target host '${target}' doesn't exist" ; return 1; 234 | fi 235 | 236 | file="${SSHGATE_DIR_TARGETS}/${target}/properties" 237 | if [ -n "${value}" ]; then 238 | [ ! -f "${file}" ] && touch "${file}" 239 | CONF_SAVE --conf-file "${file}" "${var}" "${value}" 240 | private_MAIL_APPEND "Target '${target}' configuration: ${var} = ${value}" 241 | else 242 | CONF_DEL --conf-file "${file}" "${var}" 243 | private_MAIL_APPEND "Target '${target}' configuration: ${var} removed" 244 | fi 245 | 246 | [ -f "${file}" ] && chmod a+r "${file}" # ensure file permissions 247 | return 0; 248 | } 249 | 250 | TARGET_DEL_CONF () { 251 | local target= var= file= 252 | if [ $# -ne 2 ]; then 253 | BAD_ARGUMENTS; return 1; 254 | fi 255 | 256 | target="$1"; var="$2" 257 | if [ -z "${target}" -o -z "${var}" ]; then 258 | BAD_ARGUMENTS; return 1; 259 | fi 260 | 261 | target=$( TARGET_REAL "${target}" ) 262 | if [ -z "${target}" ]; then 263 | ERROR "Target host '${target}' doesn't exist" ; return 1; 264 | fi 265 | 266 | file="${SSHGATE_DIR_TARGETS}/${target}/properties" 267 | CONF_DEL --conf-file "${file}" "${var}" 268 | [ -f "${file}" ] && chmod a+r "${file}" # ensure file permissions 269 | 270 | private_MAIL_APPEND "Target '${target}' configuration: ${var} removed" 271 | return 0; 272 | } 273 | 274 | # usage: TARGET_GET_CONF 275 | # desc: Get the value from the target configuration file 276 | TARGET_GET_CONF () { 277 | local target= var= file= 278 | if [ $# -ne 2 ]; then 279 | BAD_ARGUMENTS ; return 1; 280 | fi 281 | 282 | target="$1"; var="$2" 283 | target=$( GET_HOST "${target}" ) 284 | target=$( TARGET_REAL "${target}" ) 285 | 286 | if [ -z "${target}" ]; then 287 | ERROR "Target host '${target}' doesn't exist" ; return 1; 288 | fi 289 | if [ -z "${var}" ]; then 290 | BAD_ARGUMENTS; return 1; 291 | fi 292 | 293 | file="${SSHGATE_DIR_TARGETS}/${target}/properties" 294 | if [ -f "${file}" ]; then 295 | CONF_GET --conf-file "${file}" "${var}" 296 | eval "echo \"\${${var}}\"" 297 | fi 298 | return 0; 299 | } 300 | 301 | # usage: TARGET_LIST_ALIASES [ ] 302 | # desc: List aliases of a target host, or all aliases 303 | # note: if called without argument, list aliases of all hosts 304 | TARGET_LIST_ALIASES () { 305 | local target= t= 306 | if [ $# -eq 1 ]; then 307 | target=$( TARGET_REAL "$1" ) 308 | if [ -z "${target}" ]; then 309 | ERROR "Target host '${target}' doesn't exist" ; return 1; 310 | fi 311 | fi 312 | 313 | for file in $( find "${SSHGATE_DIR_TARGETS}/" -type l ); do 314 | t=$( readlink -f "${file}" ) 315 | [ -z "${target}" -o "${t##*/}" = "${target}" ] && echo "${file##*/}" 316 | done | sort -u 317 | return 0; 318 | } 319 | 320 | # usage: TARGET_ADD_ALIAS 321 | # desc: Add an alias name to the target host 322 | TARGET_ADD_ALIAS () { 323 | local target= 324 | if [ $# -ne 2 ]; then 325 | BAD_ARGUMENTS ; return 1; 326 | fi 327 | 328 | target=$( TARGET_REAL "$1" ); alias=$( echo "$2" | tr '[:upper:]' '[:lower:]' ) 329 | if [ -z "${target}" ]; then 330 | ERROR "Target host '${target}' doesn't exist" ; return 1 331 | fi 332 | if [ -z "${alias}" ]; then 333 | BAD_ARGUMENTS ; return 1; 334 | fi 335 | if [ -L "${SSHGATE_DIR_TARGETS}/${alias}" ]; then 336 | ERROR "Target alias '${alias}' already exists" ; return 1 337 | fi 338 | if [ -d "${SSHGATE_DIR_TARGETS}/${alias}" ]; then 339 | ERROR "Target alias '${alias}' correspond to a target host name" ; return 1 340 | fi 341 | 342 | ln -s "${SSHGATE_DIR_TARGETS}/${target}" "${SSHGATE_DIR_TARGETS}/${alias}" 343 | return 0; 344 | } 345 | 346 | # usage: TARGET_DEL_ALIAS 347 | # desc: Delete an alias name of a target host 348 | TARGET_DEL_ALIAS () { 349 | local alias= 350 | if [ $# -ne 1 ]; then 351 | BAD_ARGUMENTS ; return 1; 352 | fi 353 | 354 | alias=$( echo "$1" | tr '[:upper:]' '[:lower:]' ) 355 | if [ -z "${alias}" ]; then 356 | BAD_ARGUMENTS ; return 1; 357 | fi 358 | if [ ! -L "${SSHGATE_DIR_TARGETS}/${alias}" ]; then 359 | ERROR "Target alias '${alias}' doesn't exist" ; return 1; 360 | fi 361 | 362 | rm -f "${SSHGATE_DIR_TARGETS}/${alias}" 363 | return 0; 364 | } 365 | 366 | # usage: TARGET_REAL 367 | # desc: Get the real name of a target host 368 | # note: if real name is an empty string, the target host doesn't exist 369 | TARGET_REAL () { 370 | local target= 371 | if [ $# -ne 1 ]; then 372 | BAD_ARGUMENTS ; return 1; 373 | fi 374 | 375 | target=$( GET_HOST "$1" ) 376 | if [ -z "${target}" ]; then 377 | echo ''; return 1; 378 | fi 379 | 380 | if [ -L "${SSHGATE_DIR_TARGETS}/${target}" ]; then 381 | target=$( readlink -f "${SSHGATE_DIR_TARGETS}/${target}" ) 382 | echo "${target##*/}" 383 | else 384 | if [ -d "${SSHGATE_DIR_TARGETS}/${target}" ]; then 385 | echo "${target}" 386 | else 387 | echo '' 388 | return 1; 389 | fi 390 | fi 391 | return 0; 392 | } 393 | 394 | fi # if [ "${__TARGET_FUNC__}" != 'Loaded' ]; then 395 | -------------------------------------------------------------------------------- /COPYING: -------------------------------------------------------------------------------- 1 | GNU GENERAL PUBLIC LICENSE 2 | Version 2, June 1991 3 | 4 | Copyright (C) 1989, 1991 Free Software Foundation, Inc., 5 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 6 | Everyone is permitted to copy and distribute verbatim copies 7 | of this license document, but changing it is not allowed. 8 | 9 | Preamble 10 | 11 | The licenses for most software are designed to take away your 12 | freedom to share and change it. By contrast, the GNU General Public 13 | License is intended to guarantee your freedom to share and change free 14 | software--to make sure the software is free for all its users. This 15 | General Public License applies to most of the Free Software 16 | Foundation's software and to any other program whose authors commit to 17 | using it. (Some other Free Software Foundation software is covered by 18 | the GNU Lesser General Public License instead.) You can apply it to 19 | your programs, too. 20 | 21 | When we speak of free software, we are referring to freedom, not 22 | price. Our General Public Licenses are designed to make sure that you 23 | have the freedom to distribute copies of free software (and charge for 24 | this service if you wish), that you receive source code or can get it 25 | if you want it, that you can change the software or use pieces of it 26 | in new free programs; and that you know you can do these things. 27 | 28 | To protect your rights, we need to make restrictions that forbid 29 | anyone to deny you these rights or to ask you to surrender the rights. 30 | These restrictions translate to certain responsibilities for you if you 31 | distribute copies of the software, or if you modify it. 32 | 33 | For example, if you distribute copies of such a program, whether 34 | gratis or for a fee, you must give the recipients all the rights that 35 | you have. You must make sure that they, too, receive or can get the 36 | source code. And you must show them these terms so they know their 37 | rights. 38 | 39 | We protect your rights with two steps: (1) copyright the software, and 40 | (2) offer you this license which gives you legal permission to copy, 41 | distribute and/or modify the software. 42 | 43 | Also, for each author's protection and ours, we want to make certain 44 | that everyone understands that there is no warranty for this free 45 | software. If the software is modified by someone else and passed on, we 46 | want its recipients to know that what they have is not the original, so 47 | that any problems introduced by others will not reflect on the original 48 | authors' reputations. 49 | 50 | Finally, any free program is threatened constantly by software 51 | patents. We wish to avoid the danger that redistributors of a free 52 | program will individually obtain patent licenses, in effect making the 53 | program proprietary. To prevent this, we have made it clear that any 54 | patent must be licensed for everyone's free use or not licensed at all. 55 | 56 | The precise terms and conditions for copying, distribution and 57 | modification follow. 58 | 59 | GNU GENERAL PUBLIC LICENSE 60 | TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 61 | 62 | 0. This License applies to any program or other work which contains 63 | a notice placed by the copyright holder saying it may be distributed 64 | under the terms of this General Public License. The "Program", below, 65 | refers to any such program or work, and a "work based on the Program" 66 | means either the Program or any derivative work under copyright law: 67 | that is to say, a work containing the Program or a portion of it, 68 | either verbatim or with modifications and/or translated into another 69 | language. (Hereinafter, translation is included without limitation in 70 | the term "modification".) Each licensee is addressed as "you". 71 | 72 | Activities other than copying, distribution and modification are not 73 | covered by this License; they are outside its scope. The act of 74 | running the Program is not restricted, and the output from the Program 75 | is covered only if its contents constitute a work based on the 76 | Program (independent of having been made by running the Program). 77 | Whether that is true depends on what the Program does. 78 | 79 | 1. You may copy and distribute verbatim copies of the Program's 80 | source code as you receive it, in any medium, provided that you 81 | conspicuously and appropriately publish on each copy an appropriate 82 | copyright notice and disclaimer of warranty; keep intact all the 83 | notices that refer to this License and to the absence of any warranty; 84 | and give any other recipients of the Program a copy of this License 85 | along with the Program. 86 | 87 | You may charge a fee for the physical act of transferring a copy, and 88 | you may at your option offer warranty protection in exchange for a fee. 89 | 90 | 2. You may modify your copy or copies of the Program or any portion 91 | of it, thus forming a work based on the Program, and copy and 92 | distribute such modifications or work under the terms of Section 1 93 | above, provided that you also meet all of these conditions: 94 | 95 | a) You must cause the modified files to carry prominent notices 96 | stating that you changed the files and the date of any change. 97 | 98 | b) You must cause any work that you distribute or publish, that in 99 | whole or in part contains or is derived from the Program or any 100 | part thereof, to be licensed as a whole at no charge to all third 101 | parties under the terms of this License. 102 | 103 | c) If the modified program normally reads commands interactively 104 | when run, you must cause it, when started running for such 105 | interactive use in the most ordinary way, to print or display an 106 | announcement including an appropriate copyright notice and a 107 | notice that there is no warranty (or else, saying that you provide 108 | a warranty) and that users may redistribute the program under 109 | these conditions, and telling the user how to view a copy of this 110 | License. (Exception: if the Program itself is interactive but 111 | does not normally print such an announcement, your work based on 112 | the Program is not required to print an announcement.) 113 | 114 | These requirements apply to the modified work as a whole. If 115 | identifiable sections of that work are not derived from the Program, 116 | and can be reasonably considered independent and separate works in 117 | themselves, then this License, and its terms, do not apply to those 118 | sections when you distribute them as separate works. But when you 119 | distribute the same sections as part of a whole which is a work based 120 | on the Program, the distribution of the whole must be on the terms of 121 | this License, whose permissions for other licensees extend to the 122 | entire whole, and thus to each and every part regardless of who wrote it. 123 | 124 | Thus, it is not the intent of this section to claim rights or contest 125 | your rights to work written entirely by you; rather, the intent is to 126 | exercise the right to control the distribution of derivative or 127 | collective works based on the Program. 128 | 129 | In addition, mere aggregation of another work not based on the Program 130 | with the Program (or with a work based on the Program) on a volume of 131 | a storage or distribution medium does not bring the other work under 132 | the scope of this License. 133 | 134 | 3. You may copy and distribute the Program (or a work based on it, 135 | under Section 2) in object code or executable form under the terms of 136 | Sections 1 and 2 above provided that you also do one of the following: 137 | 138 | a) Accompany it with the complete corresponding machine-readable 139 | source code, which must be distributed under the terms of Sections 140 | 1 and 2 above on a medium customarily used for software interchange; or, 141 | 142 | b) Accompany it with a written offer, valid for at least three 143 | years, to give any third party, for a charge no more than your 144 | cost of physically performing source distribution, a complete 145 | machine-readable copy of the corresponding source code, to be 146 | distributed under the terms of Sections 1 and 2 above on a medium 147 | customarily used for software interchange; or, 148 | 149 | c) Accompany it with the information you received as to the offer 150 | to distribute corresponding source code. (This alternative is 151 | allowed only for noncommercial distribution and only if you 152 | received the program in object code or executable form with such 153 | an offer, in accord with Subsection b above.) 154 | 155 | The source code for a work means the preferred form of the work for 156 | making modifications to it. For an executable work, complete source 157 | code means all the source code for all modules it contains, plus any 158 | associated interface definition files, plus the scripts used to 159 | control compilation and installation of the executable. However, as a 160 | special exception, the source code distributed need not include 161 | anything that is normally distributed (in either source or binary 162 | form) with the major components (compiler, kernel, and so on) of the 163 | operating system on which the executable runs, unless that component 164 | itself accompanies the executable. 165 | 166 | If distribution of executable or object code is made by offering 167 | access to copy from a designated place, then offering equivalent 168 | access to copy the source code from the same place counts as 169 | distribution of the source code, even though third parties are not 170 | compelled to copy the source along with the object code. 171 | 172 | 4. You may not copy, modify, sublicense, or distribute the Program 173 | except as expressly provided under this License. Any attempt 174 | otherwise to copy, modify, sublicense or distribute the Program is 175 | void, and will automatically terminate your rights under this License. 176 | However, parties who have received copies, or rights, from you under 177 | this License will not have their licenses terminated so long as such 178 | parties remain in full compliance. 179 | 180 | 5. You are not required to accept this License, since you have not 181 | signed it. However, nothing else grants you permission to modify or 182 | distribute the Program or its derivative works. These actions are 183 | prohibited by law if you do not accept this License. Therefore, by 184 | modifying or distributing the Program (or any work based on the 185 | Program), you indicate your acceptance of this License to do so, and 186 | all its terms and conditions for copying, distributing or modifying 187 | the Program or works based on it. 188 | 189 | 6. Each time you redistribute the Program (or any work based on the 190 | Program), the recipient automatically receives a license from the 191 | original licensor to copy, distribute or modify the Program subject to 192 | these terms and conditions. You may not impose any further 193 | restrictions on the recipients' exercise of the rights granted herein. 194 | You are not responsible for enforcing compliance by third parties to 195 | this License. 196 | 197 | 7. If, as a consequence of a court judgment or allegation of patent 198 | infringement or for any other reason (not limited to patent issues), 199 | conditions are imposed on you (whether by court order, agreement or 200 | otherwise) that contradict the conditions of this License, they do not 201 | excuse you from the conditions of this License. If you cannot 202 | distribute so as to satisfy simultaneously your obligations under this 203 | License and any other pertinent obligations, then as a consequence you 204 | may not distribute the Program at all. For example, if a patent 205 | license would not permit royalty-free redistribution of the Program by 206 | all those who receive copies directly or indirectly through you, then 207 | the only way you could satisfy both it and this License would be to 208 | refrain entirely from distribution of the Program. 209 | 210 | If any portion of this section is held invalid or unenforceable under 211 | any particular circumstance, the balance of the section is intended to 212 | apply and the section as a whole is intended to apply in other 213 | circumstances. 214 | 215 | It is not the purpose of this section to induce you to infringe any 216 | patents or other property right claims or to contest validity of any 217 | such claims; this section has the sole purpose of protecting the 218 | integrity of the free software distribution system, which is 219 | implemented by public license practices. Many people have made 220 | generous contributions to the wide range of software distributed 221 | through that system in reliance on consistent application of that 222 | system; it is up to the author/donor to decide if he or she is willing 223 | to distribute software through any other system and a licensee cannot 224 | impose that choice. 225 | 226 | This section is intended to make thoroughly clear what is believed to 227 | be a consequence of the rest of this License. 228 | 229 | 8. If the distribution and/or use of the Program is restricted in 230 | certain countries either by patents or by copyrighted interfaces, the 231 | original copyright holder who places the Program under this License 232 | may add an explicit geographical distribution limitation excluding 233 | those countries, so that distribution is permitted only in or among 234 | countries not thus excluded. In such case, this License incorporates 235 | the limitation as if written in the body of this License. 236 | 237 | 9. The Free Software Foundation may publish revised and/or new versions 238 | of the General Public License from time to time. Such new versions will 239 | be similar in spirit to the present version, but may differ in detail to 240 | address new problems or concerns. 241 | 242 | Each version is given a distinguishing version number. If the Program 243 | specifies a version number of this License which applies to it and "any 244 | later version", you have the option of following the terms and conditions 245 | either of that version or of any later version published by the Free 246 | Software Foundation. If the Program does not specify a version number of 247 | this License, you may choose any version ever published by the Free Software 248 | Foundation. 249 | 250 | 10. If you wish to incorporate parts of the Program into other free 251 | programs whose distribution conditions are different, write to the author 252 | to ask for permission. For software which is copyrighted by the Free 253 | Software Foundation, write to the Free Software Foundation; we sometimes 254 | make exceptions for this. Our decision will be guided by the two goals 255 | of preserving the free status of all derivatives of our free software and 256 | of promoting the sharing and reuse of software generally. 257 | 258 | NO WARRANTY 259 | 260 | 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY 261 | FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN 262 | OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES 263 | PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED 264 | OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 265 | MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS 266 | TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE 267 | PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, 268 | REPAIR OR CORRECTION. 269 | 270 | 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING 271 | WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR 272 | REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, 273 | INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING 274 | OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED 275 | TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY 276 | YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER 277 | PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE 278 | POSSIBILITY OF SUCH DAMAGES. 279 | 280 | END OF TERMS AND CONDITIONS 281 | -------------------------------------------------------------------------------- /bin/core/target-ssh.func: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright (c) 2010 Linagora 3 | # Patrick Guiran 4 | # http://github.com/Tauop/sshGate 5 | # 6 | # sshGate is free software, you can redistribute it and/or modify 7 | # it under the terms of the GNU General Public License as 8 | # published by the Free Software Foundation; either version 2 of 9 | # the License, or (at your option) any later version. 10 | # 11 | # sshGate is distributed in the hope that it will be useful, 12 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | # GNU General Public License for more details. 15 | # 16 | # You should have received a copy of the GNU Lesser General Public License 17 | # along with this program. If not, see . 18 | # 19 | # README --------------------------------------------------------------------- 20 | # 21 | # Collection of all ssh on target related functions 22 | # 23 | # ---------------------------------------------------------------------------- 24 | 25 | if [ "${__SSHGATE_CORE__}" != 'Loaded' ]; then 26 | echo "ERROR: Only sshgate.core can load user.func."; exit 1; 27 | fi 28 | 29 | if [ "${__TARGET_SSH_FUNC__:-}" != 'Loaded' ]; then 30 | __TARGET_SSH_FUNC__='Loaded' 31 | 32 | # usage: TARGET_SSH_EDIT_CONFIG [ ] 33 | # usage: TARGET_SSH_EDIT_CONFIG [@] 34 | # desc: Edit the ssh configuration file of the for 35 | # note: if is not given, try to use default ssh login of the target 36 | # host, or the sshGate target's default ssh login 37 | # note: if is egal to "all", edit the global ssh configuration for 38 | # "Host *". In this case, we don't care about . 39 | TARGET_SSH_EDIT_CONFIG () { 40 | local target= login= file= tmpfile= bckfile= 41 | if [ $# -eq 0 -o $# -gt 2 ]; then 42 | BAD_ARGUMENTS; return 1; 43 | fi 44 | 45 | if [ "$1" != 'all' ]; then 46 | if [ $# -eq 1 ]; then 47 | target=$( GET_HOST "$1" ) 48 | login=$( GET_LOGIN "$1" ) 49 | else 50 | target="$1"; login="$2" 51 | fi 52 | 53 | target=$( TARGET_REAL "${target}" ) 54 | if [ -z "${target}" ]; then 55 | ERROR "Target host '${target} doesn't exist"; return 1; 56 | fi 57 | 58 | [ -z "${login}" ] && login=$( GET_LOGIN "${target}" ) 59 | if [ "${login}" != "${SSHGATE_TARGETS_DEFAULT_SSH_LOGIN}" ]; then 60 | # check that the login exist for the target host 61 | TARGET_SSH_LIST_LOGINS "${target}" | grep "^${login}\$" >/dev/null 62 | if [ $? -ne 0 ]; then 63 | ERROR "Login '${login}' doesn't exist for the target host '${target}'" 64 | return 1; 65 | fi 66 | fi 67 | 68 | file="${SSHGATE_DIR_TARGETS}/${target}/${SSHGATE_TARGETS_SSH_CONFIG_FILENAME}.${login}" 69 | else 70 | file="${SSHGATE_DIR_DATA}/${SSHGATE_TARGETS_SSH_CONFIG_FILENAME}.all" 71 | fi # end of : if [ "${target}" != 'all' ]; then 72 | 73 | touch "${file}" 2>/dev/null 74 | if [ $? -ne 0 ]; then 75 | ERROR "Can't write into the ssh config file"; return 1 76 | fi 77 | 78 | # backup configuration 79 | bckfile="${file}.bak" 80 | cp "${file}" "${bckfile}" 2>/dev/null 81 | if [ $? -ne 0 ]; then 82 | ERROR "Can't backup the ssh config file"; return 1 83 | fi 84 | 85 | # edit the file 86 | EDIT_FILE "${file}" 87 | if [ $? -ne 0 ]; then 88 | ERROR "Failed to edit the configuration file"; 89 | mv -f "${bckfile}" "${file}" 90 | return 1; 91 | fi 92 | 93 | tmpfile="/tmp/ssh_config.${login}.$( RANDOM )" 94 | # filter out some options and warn if they are used 95 | for opt in 'BatchMode' \ 96 | 'CheckHostIP' \ 97 | 'ControlMaster' \ 98 | 'ControlPath' \ 99 | 'ForwardAgent' \ 100 | 'IdentityFile' \ 101 | 'PreferredAuthentications' \ 102 | 'PasswordAuthentication' \ 103 | 'ProxyCommand' \ 104 | 'StrictHostKeyChecking' \ 105 | 'User' \ 106 | 'UserKnownHostsFile' ; do 107 | grep "^[[:space:]]*${opt}[[:space:]]" < "${file}" >/dev/null 108 | if [ $? -eq 0 ]; then 109 | echo "WARNING: ssh options '${opt}' was removed from editable configuration file. It's not allowed or deal by sshGate" 110 | grep -v "^[[:space:]]*${opt}[[:space:]]" < "${file}" > "${tmpfile}" 111 | mv "${tmpfile}" "${file}" 112 | fi 113 | done 114 | 115 | # cleanup 116 | rm -f "${tmpfile}" "${bckfile}" 117 | 118 | # permissions 119 | chown "${SSHGATE_GATE_ACCOUNT}" "${file}" 120 | chmod ug+r "${file}" 121 | 122 | return 0; 123 | } 124 | 125 | # usage: TARGET_SSH_GET_CONFIG [ ] 126 | # usage: TARGET_SSH_GET_CONFIG [@] 127 | # desc: Get generated ssh configuration file used to connect to the target 128 | # note: if is not given, try to use default ssh login of the target 129 | # host, or the sshGate target's default ssh login 130 | TARGET_SSH_GET_CONFIG () { 131 | local target= login= proxy= proxy_host= proxy_login= tmpfile= known_hosts_file= sshkey_file= 132 | if [ $# -eq 0 -o $# -gt 2 ]; then 133 | BAD_ARGUMENTS; return 1; 134 | fi 135 | 136 | if [ $# -eq 1 ]; then 137 | target=$( GET_HOST "$1" ) 138 | login=$( GET_LOGIN "$1" ) 139 | else 140 | target="$1"; login="$2" 141 | fi 142 | 143 | target=$( TARGET_REAL "${target}" ) 144 | if [ -z "${target}" ]; then 145 | ERROR "Target host '${target} doesn't exist"; return 1; 146 | fi 147 | 148 | [ -z "${login}" ] && login=$( GET_LOGIN "${target}" ) 149 | if [ "${login}" != "${SSHGATE_TARGETS_DEFAULT_SSH_LOGIN}" ]; then 150 | # check that the login exist for the target host 151 | TARGET_SSH_LIST_LOGINS "${target}" | grep "^${login}\$" >/dev/null 152 | if [ $? -ne 0 ]; then 153 | ERROR "Login '${login}' doesn't exist for the target host '${target}'" 154 | return 1; 155 | fi 156 | fi 157 | 158 | known_hosts_file="$( SSHGATE_ACCOUNT_HOMEDIR )/.ssh/known_hosts" 159 | sshkey_file=$( private_TARGET_PRIVATE_SSHKEY_FILE "${target}" ) 160 | tmpfile="/tmp/ssh_config.$( RANDOM )" 161 | 162 | touch "${tmpfile}" 2>/dev/null 163 | if [ $? -ne 0 ]; then 164 | ERROR "Can't write to temporary file"; return 1; 165 | fi 166 | 167 | proxy=$( TARGET_GET_CONF "${target}" SSH_PROXY ) 168 | if [ -n "${proxy}" ]; then 169 | proxy_host=$( GET_HOST "${proxy}" ) 170 | proxy_host=$( TARGET_REAL "${proxy_host}" ) 171 | proxy_login=$( GET_LOGIN "${proxy}" ) 172 | if [ -z "${proxy_host}" ]; then 173 | ERROR "Target '${target}' was declared to need proxy target '${proxy_host}' whereas '${proxy_host}' doesn't exist"; 174 | return 1; 175 | else 176 | rm -f "${tmpfile}" # we don't use previous 'touched' file 177 | tmpfile=$( TARGET_SSH_GET_CONFIG "${proxy_host}" "${proxy_login}" ) 178 | fi 179 | else 180 | # no proxy, but have to get the global ssh configuration 181 | echo "Host *" >> "${tmpfile}" 182 | echo " IdentityFile ${SSHGATE_TARGET_DEFAULT_PRIVATE_SSHKEY_FILE}" >> "${tmpfile}" 183 | echo " IdentitiesOnly yes" >> "${tmpfile}" 184 | echo " PasswordAuthentication no" >> "${tmpfile}" 185 | echo " StrictHostKeyChecking yes" >> "${tmpfile}" 186 | echo " HashKnownHosts no" >> "${tmpfile}" 187 | echo " UserKnownHostsFile ${known_hosts_file}" >> "${tmpfile}" 188 | if [ -r "${SSHGATE_DIR_DATA}/${SSHGATE_TARGETS_SSH_CONFIG_FILENAME}.all" ]; then 189 | cat "${SSHGATE_DIR_DATA}/${SSHGATE_TARGETS_SSH_CONFIG_FILENAME}.all" >> "${tmpfile}" 190 | fi 191 | fi # end of : if [ -n "${proxy}" ]; then 192 | 193 | echo >> "${tmpfile}" 194 | echo "Host ${target}" >> "${tmpfile}" 195 | echo " IdentityFile ${sshkey_file}" >> "${tmpfile}" 196 | echo " IdentitiesOnly yes" >> "${tmpfile}" 197 | echo " PasswordAuthentication no" >> "${tmpfile}" 198 | echo " StrictHostKeyChecking yes" >> "${tmpfile}" 199 | echo " User ${login}" >> "${tmpfile}" 200 | if [ -n "${proxy}" ]; then 201 | echo " ProxyCommand ssh -F ${tmpfile} ${proxy} nc %h %p" >> "${tmpfile}" 202 | fi 203 | if [ -r "${SSHGATE_DIR_TARGETS}/${target}/${SSHGATE_TARGETS_SSH_CONFIG_FILENAME}.${login}" ]; then 204 | cat "${SSHGATE_DIR_TARGETS}/${target}/${SSHGATE_TARGETS_SSH_CONFIG_FILENAME}.${login}" >> "${tmpfile}" 205 | fi 206 | 207 | echo "${tmpfile}" 208 | return 0; 209 | } 210 | 211 | # usage: TARGET_SSH_DISPLAY_GLOBAL_CONFIG 212 | # desc: Display global ssh configuration file used, which declare options for "Host *" 213 | TARGET_SSH_DISPLAY_GLOBAL_CONFIG () { 214 | local file="${SSHGATE_DIR_DATA}/${SSHGATE_TARGETS_SSH_CONFIG_FILENAME}.all" 215 | [ -f "${file}" ] && cat "${file}" 216 | return 0; 217 | } 218 | 219 | # usage: TARGET_SSH_DISPLAY_CONFIG [ ] 220 | # usage: TARGET_SSH_DISPLAY_CONFIG [@] 221 | # desc: Display simple ssh configuration file used to connect to with 222 | # note: if is not given, try to use default ssh login of the target 223 | # host, or the sshGate target's default ssh login 224 | TARGET_SSH_DISPLAY_CONFIG () { 225 | local target= login= 226 | if [ $# -eq 0 -o $# -gt 2 ]; then 227 | BAD_ARGUMENTS; return 1; 228 | fi 229 | 230 | if [ $# -eq 1 ]; then 231 | target=$( GET_HOST "$1" ); 232 | login=$( GET_LOGIN "$1" ); 233 | else 234 | target="$1"; login="$2" 235 | fi 236 | 237 | target=$( TARGET_REAL "${target}" ) 238 | if [ -z "${target}" ]; then 239 | ERROR "Target host '${target} doesn't exist"; return 1; 240 | fi 241 | 242 | [ -z "${login}" ] && login=$( GET_LOGIN "${target}" ) 243 | if [ "${login}" != "${SSHGATE_TARGETS_DEFAULT_SSH_LOGIN}" ]; then 244 | # check that the login exist for the target host 245 | TARGET_SSH_LIST_LOGINS "${target}" | grep "^${login}\$" >/dev/null 246 | if [ $? -ne 0 ]; then 247 | ERROR "Login '${login}' doesn't exist for the target host '${target}'" 248 | return 1; 249 | fi 250 | fi 251 | 252 | if [ -r "${SSHGATE_DIR_TARGETS}/${target}/${SSHGATE_TARGETS_SSH_CONFIG_FILENAME}.${login}" ]; then 253 | cat "${SSHGATE_DIR_TARGETS}/${target}/${SSHGATE_TARGETS_SSH_CONFIG_FILENAME}.${login}" 254 | fi 255 | return 0; 256 | } 257 | 258 | # usage: TARGET_SSH_DISPLAY_FULL_CONFIG [ ] 259 | # usage: TARGET_SSH_DISPLAY_FULL_CONFIG [@] 260 | # desc: Display full generated ssh configuration file used to connect to the target 261 | # note: if is not given, try to use default ssh login of the target 262 | # host, or the sshGate target's default ssh login 263 | TARGET_SSH_DISPLAY_FULL_CONFIG () { 264 | local target= login= file= 265 | if [ $# -eq 0 -o $# -gt 2 ]; then 266 | BAD_ARGUMENTS; return 1; 267 | fi 268 | 269 | if [ $# -eq 1 ]; then 270 | target=$( GET_HOST "$1" ) 271 | login=$( GET_LOGIN "$1" ) 272 | else 273 | target="$1"; login="$2" 274 | fi 275 | 276 | target=$( TARGET_REAL "${target}" ) 277 | if [ -z "${target}" ]; then 278 | ERROR "Target host '${target} doesn't exist"; return 1; 279 | fi 280 | 281 | [ -z "${login}" ] && login=$( GET_LOGIN "${target}" ) 282 | if [ "${login}" != "${SSHGATE_TARGETS_DEFAULT_SSH_LOGIN}" ]; then 283 | # check that the login exist for the target host 284 | TARGET_SSH_LIST_LOGINS "${target}" | grep "^${login}\$" >/dev/null 285 | if [ $? -ne 0 ]; then 286 | ERROR "Login '${login}' doesn't exist for the target host '${target}'" 287 | return 1; 288 | fi 289 | fi 290 | 291 | file=$( TARGET_SSH_GET_CONFIG "${target}" "${login}" ) 292 | # sed is needed to remove reference of the temporary generated file 293 | cat "${file}" | sed -e "s|${file}|ssh_conf_file|g"; 294 | rm -f "${file}" 295 | return 0; 296 | } 297 | 298 | # usage: TARGET_SSH_LIST_LOGINS 299 | # desc: List all available ssh logins of target 300 | TARGET_SSH_LIST_LOGINS () { 301 | local target= file= 302 | if [ $# -ne 1 ]; then 303 | BAD_ARGUMENTS ; return 1; 304 | fi 305 | 306 | target=$( TARGET_REAL "$1" ) 307 | if [ -z "${target}" ]; then 308 | ERROR "Target host '${target}' doesn't exist" ; return 1; 309 | fi 310 | 311 | file="${SSHGATE_DIR_TARGETS}/${target}/${SSHGATE_TARGETS_SSH_LOGINS_FILENAME}" 312 | ( [ -f "${file}" ] && cat "${file}"; 313 | TARGET_GET_CONF "${target}" DEFAULT_SSH_LOGIN ) | grep -v '^$' | sort -u 314 | return 0; 315 | } 316 | 317 | # usage: TARGET_SSH_ADD_LOGIN 318 | # desc: Add a ssh login to the target 319 | TARGET_SSH_ADD_LOGIN () { 320 | local target= file= login= 321 | if [ $# -ne 2 ]; then 322 | BAD_ARGUMENTS ; return 1; 323 | fi 324 | 325 | target="$1"; login="$2" 326 | target=$( TARGET_REAL "${target}" ) 327 | if [ -z "${target}" ]; then 328 | ERROR "Target host '${target}' doesn't exist" ; return 1; 329 | fi 330 | 331 | file="${SSHGATE_DIR_TARGETS}/${target}/${SSHGATE_TARGETS_SSH_LOGINS_FILENAME}" 332 | if [ ! -f "${file}" ]; then 333 | touch "${file}" 334 | else 335 | grep "^${login}$" < "${file}" >/dev/null 336 | if [ $? -eq 0 ]; then 337 | ERROR "Login '${login}' already exists for target '${target}'"; return 1; 338 | fi 339 | fi # end of : if [ ! -f "${file}" ]; then 340 | 341 | echo "${login}" >> "${file}" 342 | # create empty access files 343 | touch "${SSHGATE_DIR_TARGETS}/${target}/${SSHGATE_TARGETS_USER_ACCESS_FILENAME}.${login}" 344 | touch "${SSHGATE_DIR_TARGETS}/${target}/${SSHGATE_TARGETS_USERGROUP_ACCESS_FILENAME}.${login}" 345 | 346 | return 0; 347 | } 348 | 349 | # usage: TARGET_SSH_DEL_LOGIN 350 | # desc: Remove a ssh l_DELogin from the target 351 | TARGET_SSH_DEL_LOGIN () { 352 | local target= login= file= tmp_file= 353 | if [ $# -ne 2 ]; then 354 | BAD_ARGUMENTS ; return 1; 355 | fi 356 | 357 | target="$1"; login="$2" 358 | [ "${login}" = "${SSHGATE_TARGETS_DEFAULT_SSH_LOGIN}" ] && return 0; 359 | 360 | target=$( TARGET_REAL "${target}" ) 361 | if [ -z "${target}" ]; then 362 | ERROR "Target host '${target}' doesn't exist" ; return 1; 363 | fi 364 | 365 | file="${SSHGATE_DIR_TARGETS}/${target}/${SSHGATE_TARGETS_SSH_LOGINS_FILENAME}" 366 | tmp_file="/tmp/file.$( RANDOM )" 367 | 368 | [ ! -e "${file}" ] && return 0; 369 | grep -v "^${login}$" < "${file}" > "${tmp_file}" 370 | mv "${tmp_file}" "${file}" 371 | 372 | # delete access files 373 | rm -f "${SSHGATE_DIR_TARGETS}/${target}/${SSHGATE_TARGETS_USER_ACCESS_FILENAME}.${login}" 374 | rm -f "${SSHGATE_DIR_TARGETS}/${target}/${SSHGATE_TARGETS_USERGROUP_ACCESS_FILENAME}.${login}" 375 | 376 | return 0; 377 | } 378 | 379 | # usage: TARGET_SSH_RUN_COMMAND [@] 380 | # desc: Execute a command on the remote target host 381 | # note: if isn't given, use the target's default ssh login 382 | TARGET_SSH_RUN_COMMAND () { 383 | local target= login= remote_command= ssh_conf_file= result= 384 | if [ $# -ne 2 ]; then 385 | BAD_ARGUMENTS ; return 1; 386 | fi 387 | 388 | target=$( GET_HOST "$1" ) 389 | login=$( GET_LOGIN "$1" ) 390 | remote_command="$2" 391 | if [ -z "${target}" ]; then 392 | ERROR "Target host '${target}' doesn't exist"; return 1; 393 | fi 394 | 395 | ssh_conf_file=$( TARGET_SSH_GET_CONFIG "${target}" "${login}" ) 396 | [ $? -ne 0 ] && return 1; 397 | ssh -o "ConnectTimeout 5" \ 398 | -F "${ssh_conf_file}" \ 399 | "${login}@${target}" \ 400 | "${remote_command}" 2>/dev/null 401 | result=$? 402 | rm -f "${ssh_conf_file}" 403 | return ${result} 404 | } 405 | 406 | # usage: TARGET_SSH_TEST [@] 407 | # desc: Test to connect to the target 408 | TARGET_SSH_TEST () { 409 | local target= login= ssh_conf_file= sshkey_file= reply= 410 | if [ $# -eq 0 -o $# -gt 2 ]; then 411 | BAD_ARGUMENTS ; return 1; 412 | fi 413 | 414 | target=$( GET_HOST "$1" ) 415 | login=$( GET_LOGIN "$1" ) 416 | target=$( TARGET_REAL "${target}" ) 417 | if [ -z "${target}" ]; then 418 | ERROR "Target host '${target}' doesn't exist" ; return 1; 419 | fi 420 | 421 | echo -n "- ${login}@${target} ... " 422 | ssh_conf_file=$( TARGET_SSH_GET_CONFIG "${target}" "${login}" ) 423 | reply=$( ssh -o "ConnectTimeout 5" \ 424 | -o "BatchMode yes" \ 425 | -F "${ssh_conf_file}" \ 426 | "${login}@${target}" "echo 'test'" 2>&1 ) 427 | if [ $? -eq 0 -a "${reply}" = 'test' ]; then 428 | echo 'OK'; 429 | else 430 | echo 'KO'; 431 | echo " ${reply}" | sed -e $'s/\r//'; 432 | fi 433 | 434 | rm -f "${ssh_conf_file}" 435 | return 0; 436 | } 437 | 438 | # usage: TARGET_SSH_TEST_ALL 439 | # desc: Test to connect to all target. 440 | # important: this take a while to test ssh connection on all target 441 | TARGET_SSH_TEST_ALL () { 442 | echo "= Test all targets ssh connectivity =" 443 | for target in $( TARGETS_LIST ); do 444 | for login in $( TARGET_SSH_LIST_LOGINS "${target}" ); do 445 | TARGET_SSH_TEST "${login}@${target}" 446 | done 447 | done 448 | } 449 | 450 | 451 | fi # end of: if [ "${__TARGET_SSH_FUNC__:-}" != 'Loaded' ]; then 452 | -------------------------------------------------------------------------------- /bin/core/user.func: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright (c) 2010 Linagora 3 | # Patrick Guiran 4 | # http://github.com/Tauop/sshGate 5 | # 6 | # sshGate is free software, you can redistribute it and/or modify 7 | # it under the terms of the GNU General Public License as 8 | # published by the Free Software Foundation; either version 2 of 9 | # the License, or (at your option) any later version. 10 | # 11 | # sshGate is distributed in the hope that it will be useful, 12 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | # GNU General Public License for more details. 15 | # 16 | # You should have received a copy of the GNU Lesser General Public License 17 | # along with this program. If not, see . 18 | # 19 | # README --------------------------------------------------------------------- 20 | # 21 | # Collection of all users related functions 22 | # 23 | # ---------------------------------------------------------------------------- 24 | 25 | if [ "${__SSHGATE_CORE__}" != 'Loaded' ]; then 26 | echo "ERROR: Only sshgate.core can load user.func."; exit 1; 27 | fi 28 | 29 | if [ "${__USER_FUNC__:-}" != 'Loaded' ]; then 30 | __USER_FUNC__='Loaded' 31 | 32 | # usage: USERS_LIST 33 | # desc: List all users 34 | USERS_LIST () { 35 | local res= find_opt= 36 | [ $# -eq 1 ] && find_opt="-iname '$1'" 37 | 38 | res=$( eval "find '${SSHGATE_DIR_USERS}' -type f ${find_opt} -printf '%P\n'" ) 39 | echo "${res}" | grep -v '[.]properties$' | sort -u 40 | return 0; 41 | } 42 | 43 | # usage: USER_ADD 44 | # desc: Add a new user 45 | USER_ADD () { 46 | local user= userkey= usermail= tmpfile= 47 | if [ $# -ne 2 ]; then 48 | BAD_ARGUMENTS ; return 1; 49 | fi 50 | 51 | user="$1"; usermail="$2" 52 | if [ -z "${user}" -o -z "${usermail}" ]; then 53 | BAD_ARGUMENTS ; return 1; 54 | fi 55 | 56 | echo "${user}" | grep ' ' >/dev/null 57 | if [ $? -eq 0 -o -z "${user}" ]; then 58 | ERROR "${user} is not a valid username" ; return 1 59 | fi 60 | 61 | if [ -f "${SSHGATE_DIR_USERS}/${user}" ]; then 62 | ERROR "User '${user}' already exists" ; return 1; 63 | fi 64 | 65 | echo "${usermail}" | grep '@' >/dev/null 66 | if [ $? -ne 0 ]; then 67 | ERROR "Invalid user e-mail" ; return 1; 68 | fi 69 | 70 | USER_SSHKEY_EDIT "${user}" 71 | private_USER_AUTH_KEYS_ADD "${user}" 72 | 73 | private_MAIL_APPEND "User ${user} added" 74 | USER_SET_CONF "${user}" MAIL "${usermail}" 75 | 76 | return 0 77 | } 78 | 79 | # usage: USER_DEL 80 | # desc: Delete a user 81 | USER_DEL () { 82 | local user= usergroup= 83 | if [ $# -ne 1 ]; then 84 | BAD_ARGUMENTS ; return 1 85 | fi 86 | 87 | user="$1" 88 | if [ ! -f "${SSHGATE_DIR_USERS}/${user}" -o -z "${user}" ]; then 89 | ERROR "User '${user}' doesn't exist" ; return 1; 90 | fi 91 | 92 | # delete user from groups 93 | for usergroup in $( USER_LIST_USERGROUPS "${user}" ); do 94 | private_ACL_FILE_DEL "${user}" "${SSHGATE_DIR_USERS_GROUPS}/${usergroup}" 95 | done 96 | 97 | # delete user from target access list 98 | for target in $( USER_LIST_TARGETS "${user}" ); do 99 | login=$( GET_LOGIN "${target}" ) 100 | target=$( GET_HOST "${target}" ) 101 | private_ACL_FILE_DEL "${user}" "${SSHGATE_DIR_TARGETS}/${target}/${SSHGATE_TARGETS_USER_ACCESS_FILENAME}.${login}" 102 | done 103 | 104 | private_USER_AUTH_KEYS_DEL "${user}" 105 | 106 | rm -f "${SSHGATE_DIR_USERS}/${user}" 107 | rm -f "${SSHGATE_DIR_USERS}/${user}.properties" 108 | private_MAIL_APPEND "User ${user} removed" 109 | 110 | return 0 111 | } 112 | 113 | # usage: USER_DISPLAY_CONF 114 | # desc: Display user configuration 115 | USER_DISPLAY_CONF () { 116 | local user= file= 117 | if [ $# -ne 1 ]; then 118 | BAD_ARGUMENTS; return 1; 119 | fi 120 | 121 | user="$1" 122 | if [ ! -f "${SSHGATE_DIR_USERS}/${user}" -o -z "${user}" ]; then 123 | ERROR "User '${user}' doesn't exist"; return 1; 124 | fi 125 | 126 | file="${SSHGATE_DIR_USERS}/${user}.properties" 127 | if [ ! -f "${file}" ]; then 128 | NOTICE "User '${user}' has no configuration file" 129 | else 130 | cat "${file}" 131 | fi 132 | return 0 133 | } 134 | 135 | # usage: USER_SET_CONF 136 | # desc: Set a variable/value pair into the user configuration 137 | # note: if no is given, the is removed from the 138 | # configuration file of the 139 | USER_SET_CONF () { 140 | local user= var= value= file= 141 | if [ $# -lt 2 -o $# -gt 3 ]; then 142 | BAD_ARGUMENTS; return 1; 143 | fi 144 | 145 | user="$1"; var="$2" 146 | [ $# -eq 3 ] && value="$3" 147 | 148 | if [ -z "${user}" -o -z "${var}" ]; then 149 | BAD_ARGUMENTS; return 1; 150 | fi 151 | if [ ! -f "${SSHGATE_DIR_USERS}/${user}" -o -z "${user}" ]; then 152 | ERROR "User '${user}' doesn't exist"; return 1; 153 | fi 154 | 155 | file="${SSHGATE_DIR_USERS}/${user}.properties" 156 | if [ -n "${value}" ]; then 157 | [ ! -f "${file}" ] && touch "${file}" 158 | chown "${SSHGATE_GATE_ACCOUNT}" "${file}" # ensure that sshgate-bridge can read/write this file 159 | CONF_SAVE --conf-file "${file}" "${var}" "${value}" 160 | private_MAIL_APPEND "User '${user}' configuration: ${var} = ${value}" 161 | else 162 | CONF_DEL --conf-file "${file}" "${var}" 163 | [ ! -s "${file}" ] && rm -f "${file}" 164 | private_MAIL_APPEND "User '${user}' configuration: ${var} removed" 165 | fi 166 | 167 | if [ -f "${file}" ]; then 168 | chmod a+r "${file}" # ensure dans file permissions are good 169 | chown "${SSHGATE_GATE_ACCOUNT}" "${file}" 170 | fi 171 | return 0; 172 | } 173 | 174 | # usage: USER_DEL_CONF 175 | # desc: Delete a variable from the user configuration 176 | USER_DEL_CONF () { 177 | local user= var= file= 178 | if [ $# -ne 2 ]; then 179 | BAD_ARGUMENTS; return 1; 180 | fi 181 | 182 | user="$1"; var="$2" 183 | if [ -z "${user}" -o -z "${var}" ]; then 184 | BAD_ARGUMENTS; return 1; 185 | fi 186 | if [ ! -f "${SSHGATE_DIR_USERS}/${user}" -o -z "${user}" ]; then 187 | ERROR "User '${user}' doesn't exist"; return 1; 188 | fi 189 | 190 | file="${SSHGATE_DIR_USERS}/${user}.properties" 191 | CONF_DEL --conf-file "${file}" "${var}" 192 | [ ! -s "${file}" ] && rm -f "${file}" 193 | if [ -f "${file}" ]; then 194 | chmod a+r "${file}" # ensure dans file permissions are good 195 | chown "${SSHGATE_GATE_ACCOUNT}" "${file}" 196 | fi 197 | 198 | private_MAIL_APPEND "User '${user}' configuration: ${var} removed" 199 | return 0; 200 | } 201 | 202 | # usage: USER_GET_CONF 203 | # desc: Get a variable value from the user configuration 204 | USER_GET_CONF () { 205 | local user= var= file= 206 | if [ $# -ne 2 ]; then 207 | BAD_ARGUMENTS; return 1; 208 | fi 209 | 210 | user="$1"; var="$2" 211 | 212 | if [ -z "${user}" -o -z "${var}" ]; then 213 | BAD_ARGUMENTS; return 1; 214 | fi 215 | if [ ! -f "${SSHGATE_DIR_USERS}/${user}" -o -z "${user}" ]; then 216 | ERROR "User '${user}' doesn't exist"; return 1; 217 | fi 218 | 219 | file="${SSHGATE_DIR_USERS}/${user}.properties" 220 | if [ -f "${file}" ]; then 221 | CONF_GET --conf-file "${file}" "${var}" 222 | eval "echo \"\${${var}}\"" 223 | fi 224 | return 0 225 | } 226 | 227 | # usage: USER_LIST_USERGROUPS 228 | # desc: List usergroups of the user 229 | USER_LIST_USERGROUPS () { 230 | local user= usergroup= 231 | if [ $# -ne 1 ]; then 232 | BAD_ARGUMENTS ; return 1; 233 | fi 234 | 235 | user="$1" 236 | if [ ! -f "${SSHGATE_DIR_USERS}/${user}" -o -z "${user}" ]; then 237 | ERROR "User '${user}' doesn't exist" ; return 1; 238 | fi 239 | 240 | for usergroup in $( grep -l -r "^${user}\$" "${SSHGATE_DIR_USERS_GROUPS}/" | sort -u ); do 241 | echo "${usergroup##*/}" 242 | done | sort -u 243 | return 0; 244 | } 245 | 246 | # usage: USER_LIST_TARGETS 247 | # desc: List all target host, which the has access to 248 | USER_LIST_TARGETS () { 249 | local user= target= is_restricted= 250 | if [ $# -ne 1 ]; then 251 | BAD_ARGUMENTS ; return 1; 252 | fi 253 | 254 | user="$1" 255 | if [ ! -f "${SSHGATE_DIR_USERS}/${user}" -o -z "${user}" ]; then 256 | ERROR "User '${user}' doesn't exist" ; return 1; 257 | fi 258 | 259 | is_restricted=$( USER_GET_CONF "${user}" IS_RESTRICTED ) 260 | if [ "${is_restricted}" = 'false' ]; then 261 | for target in $( TARGETS_LIST ); do 262 | for login in $( TARGET_SSH_LIST_LOGINS "${target}" ); do 263 | echo "${login}@${target}" 264 | done 265 | done 266 | else 267 | ( # subshell :( 268 | # direct access 269 | for target in $( find "${SSHGATE_DIR_TARGETS}" \ 270 | -name "${SSHGATE_TARGETS_USER_ACCESS_FILENAME}*" \ 271 | -exec grep -l "^${user}\$" {} \; ); do 272 | target=$( echo "${target}" | sed -e "s|^.*/\([^/]*\)/${SSHGATE_TARGETS_USER_ACCESS_FILENAME}.\(.*\)$|\2@\1|" ) 273 | echo "${target}" 274 | done 275 | 276 | # access through usergroup 277 | for usergroup in $( USER_LIST_USERGROUPS "${user}" ); do 278 | USERGROUP_LIST_TARGETS "${usergroup}" 279 | done 280 | ) | sort -u 281 | fi # end of : if [ "${is_restricted}" = 'false' ]; then 282 | return 0; 283 | } 284 | 285 | # usage: USER_ACCESS_INFO 286 | # desc: List all user's access, and how those access are granted 287 | USER_ACCESS_INFO () { 288 | local user= target= usergroup= is_restricted= 289 | if [ $# -ne 1 ]; then 290 | BAD_ARGUMENTS ; return 1; 291 | fi 292 | 293 | user="$1" 294 | if [ ! -f "${SSHGATE_DIR_USERS}/${user}" -o -z "${user}" ]; then 295 | ERROR "User '${user}' doesn't exist" ; return 1; 296 | fi 297 | 298 | # direct access 299 | for target in $( find "${SSHGATE_DIR_TARGETS}" \ 300 | -name "${SSHGATE_TARGETS_USER_ACCESS_FILENAME}*" \ 301 | -exec grep -l "^${user}\$" {} \; | sort -u ); do 302 | target=$( echo "${target}" | sed -e "s|^.*/\([^/]*\)/${SSHGATE_TARGETS_USER_ACCESS_FILENAME}.\(.*\)$|\2@\1|" ) 303 | echo " ${user} ---> ${target}" 304 | done 305 | 306 | # access through usergroup 307 | for usergroup in $( USER_LIST_USERGROUPS "${user}" ); do 308 | for target in $( find "${SSHGATE_DIR_TARGETS}" \ 309 | -name "${SSHGATE_TARGETS_USERGROUP_ACCESS_FILENAME}*" \ 310 | -exec grep -l "^${usergroup}\$" {} \; | sort -u ); do 311 | target=$( echo "${target}" | sed -e "s|^.*/\([^/]*\)/${SSHGATE_TARGETS_USERGROUP_ACCESS_FILENAME}.\(.*\)$|\2@\1|" ) 312 | echo " ${user} --- usergroup(${usergroup}) ---> ${target}" 313 | done 314 | done 315 | 316 | is_restricted=$( USER_GET_CONF "${user}" IS_RESTRICTED ) 317 | if [ "${is_restricted}" = 'false' ]; then 318 | echo 319 | echo "NOTICE: User has access to whole target host, as its configuration IS_RESTRICTED variable is set to 'false'."; 320 | echo 321 | fi 322 | return 0; 323 | } 324 | 325 | # usage: USER_ACCESS_NOTIFY 326 | # desc: Send a mail to the user to notify him about its access 327 | USER_ACCESS_NOTIFY () { 328 | local user= user_mail= mail_file= old_mail_file= aliases= 329 | if [ $# -ne 1 ]; then 330 | BAD_ARGUMENTS ; return 1; 331 | fi 332 | 333 | user="$1" 334 | user_mail=$( USER_GET_CONF "${user}" MAIL ) 335 | if [ -z "${user_mail}" ]; then 336 | ERROR "No e-mail was setup for user '${user}'"; return 1; 337 | fi 338 | 339 | old_mail_file=$( MAIL_GET_FILE ) 340 | MAIL_CREATE 341 | 342 | MAIL_APPEND "Hi," 343 | MAIL_APPEND '' 344 | MAIL_APPEND "Here is the list of your access of sshGate :" 345 | MAIL_APPEND '' 346 | for target in $( USER_LIST_TARGETS "${user}" ); do 347 | [ -z "${target}" ] && continue; 348 | MAIL_APPEND " - ${target}" 349 | aliases= 350 | aliases=$( TARGET_LIST_ALIASES "${target}" ) 351 | if [ "${aliases}" != '' ]; then 352 | aliases=$( echo "${aliases}" | tr $'\n' ',' ) 353 | MAIL_APPEND " alias: ${aliases}" 354 | fi 355 | done 356 | MAIL_SEND "Your sshGate access" "${user_mail}" 357 | 358 | MAIL_SET_FILE "${old_mail_file}" 359 | return 0 360 | } 361 | 362 | 363 | # usage: private_USER_SSHKEY_FILE 364 | # desc: echo-return the path to the user sshkey file 365 | private_USER_SSHKEY_FILE () { 366 | local user= f= 367 | if [ $# -ne 1 ]; then 368 | BAD_ARGUMENTS ; return 1; 369 | fi 370 | user="$1" 371 | f="${SSHGATE_DIR_USERS}/${user}" 372 | [ ! -r "$f" -o -z "${user}" ] && f='' 373 | echo "$f" 374 | return 0; 375 | } 376 | 377 | # usage: USER_SSHKEY_EDIT 378 | # desc: edit the public sshkey file of 379 | USER_SSHKEY_EDIT () { 380 | local user= tmpfile= 381 | if [ $# -ne 1 ]; then 382 | BAD_ARGUMENTS ; return 1; 383 | fi 384 | 385 | user="$1" 386 | if [ -z "${user}" ]; then 387 | ERROR "User name is empty"; return 1; 388 | fi 389 | 390 | touch "${SSHGATE_DIR_USERS}/${user}" 391 | if [ $? -ne 0 ]; then 392 | ERROR "Can't write into user file"; return 1; 393 | fi 394 | 395 | tmpfile="/tmp/file.$( RANDOM )" 396 | touch "${tmpfile}" 397 | echo "# Put the SSH public key for '${user}' here. Then save & quit from the editor" >> "${tmpfile}" 398 | echo "# line begins by '#' will be removed" >> "${tmpfile}" 399 | EDIT_FILE "${tmpfile}" 400 | 401 | grep -v '^#' < "${tmpfile}" > "${SSHGATE_DIR_USERS}/${user}" 402 | rm -f "${tmpfile}" > /dev/null 2>/dev/null 403 | 404 | private_USER_AUTH_KEYS_DEL "${user}" || return 1; 405 | private_USER_AUTH_KEYS_ADD "${user}" || return 1; 406 | 407 | return 0; 408 | } 409 | 410 | # usage: DISPLAY_USER_SSHKEY_FILE 411 | # usage: USER_SSHKEY_DISPLAY 412 | # desc: Display the public sshkey of a user 413 | USER_SSHKEY_DISPLAY () { 414 | local user= 415 | 416 | if [ $# -ne 1 ]; then 417 | BAD_ARGUMENTS ; return 1; 418 | fi 419 | 420 | user="$1" 421 | if [ ! -f "${SSHGATE_DIR_USERS}/${user}" ]; then 422 | ERROR "User '${user}' doesn't exist"; return 1; 423 | fi 424 | 425 | echo "# public sshkey ${user}" 426 | cat "${SSHGATE_DIR_USERS}/${user}"; 427 | 428 | return 0; 429 | } 430 | 431 | # usage: private_USER_AUTH_KEYS_ADD 432 | # desc: Add a user public sshkey file into authorized_keys 433 | private_USER_AUTH_KEYS_ADD () { 434 | local user= authorized_keys2= file= user_key= 435 | 436 | if [ $# -ne 1 -a $# -ne 2 ]; then 437 | BAD_ARGUMENTS; return 1; 438 | fi 439 | 440 | user="$1" 441 | if [ ! -f "${SSHGATE_DIR_USERS}/${user}" -o -z "${user}" ]; then 442 | ERROR "user '${user}' doesn't exist"; return 1; 443 | fi 444 | 445 | [ $# -eq 2 ] && authorized_keys2="$2" || authorized_keys2="$( SSHGATE_ACCOUNT_HOMEDIR )/.ssh/authorized_keys2" 446 | touch "${authorized_keys2}" 2>/dev/null 447 | if [ $? -ne 0 ]; then 448 | ERROR "Can't write into authorized_keys2 file '${authorized_keys2}'" 449 | return 1; 450 | fi 451 | 452 | user_key=$( cat "${SSHGATE_DIR_USERS}/${user}" ) 453 | echo "command=\"/bin/sh ${SSHGATE_DIR_BIN}/sshgate-bridge ${user}\" ${user_key}" >> "${authorized_keys2}" 454 | 455 | chown "${SSHGATE_GATE_ACCOUNT}" "${authorized_keys2}" 456 | chmod u+r "${authorized_keys2}" 457 | return 0; 458 | } 459 | 460 | # usage: private_USER_AUTH_KEYS_DEL [] 461 | # desc: remove a user public sshkey file from the authorized_keys2 file 462 | private_USER_AUTH_KEYS_DEL () { 463 | local user= authorized_keys2= file= tmp_file= 464 | 465 | if [ $# -ne 1 -a $# -ne 2 ]; then 466 | bad_arguments ; return 1; 467 | fi 468 | 469 | user="$1" 470 | if [ ! -f "${SSHGATE_DIR_USERS}/${user}" -o -z "${user}" ]; then 471 | ERROR "User '${user}' doesn't exist"; return 1; 472 | fi 473 | 474 | [ $# -eq 2 ] && authorized_keys2="$2" || authorized_keys2="$( SSHGATE_ACCOUNT_HOMEDIR )/.ssh/authorized_keys2" 475 | touch "${authorized_keys2}" 2>/dev/null 476 | if [ $? -ne 0 ]; then 477 | ERROR "Can't write into authorized_keys2 file '${authorized_keys2}'" 478 | return 1; 479 | fi 480 | 481 | tmp_file="/tmp/file.$( RANDOM )" 482 | touch "${tmp_file}" 2>/dev/null 483 | if [ $? -ne 0 ]; then 484 | ERROR "Can't write into temporary file '${tmpfile}'"; return 1 485 | fi 486 | 487 | grep -v "^command=\"/bin/sh ${SSHGATE_DIR_BIN}/sshgate-bridge ${user}\" " < "${authorized_keys2}" > "${tmp_file}" 488 | mv "${tmp_file}" "${authorized_keys2}" 489 | 490 | chown "${SSHGATE_GATE_ACCOUNT}" "${authorized_keys2}" 491 | chmod u+r "${authorized_keys2}" 492 | return 0; 493 | } 494 | 495 | # usage: USER_AUTH_KEYS_UPDATE 496 | # desc: update the user public sshkey in the authorized_keys2 file 497 | USER_AUTH_KEYS_UPDATE () { 498 | local user= 499 | 500 | if [ $# -ne 1 ]; then 501 | BAD_ARGUMENTS ; return 1; 502 | fi 503 | 504 | user="$1" 505 | if [ ! -f "${SSHGATE_DIR_USERS}/${user}" ]; then 506 | ERROR "User '${user}' doesn't exist"; return 1; 507 | fi 508 | 509 | private_USER_AUTH_KEYS_DEL "${user}" || return 1; 510 | private_USER_AUTH_KEYS_ADD "${user}" || return 1; 511 | 512 | return 0; 513 | } 514 | 515 | # usage: USERS_AUTH_KEYS_BUILD 516 | # desc: re-build the whole authorized_keys2 file 517 | USERS_AUTH_KEYS_BUILD () { 518 | local user= authorized_keys2= 519 | 520 | authorized_keys2="$( SSHGATE_ACCOUNT_HOMEDIR )/.ssh/authorized_keys2" 521 | touch "${authorized_keys2}" 2>/dev/null 522 | if [ $? -ne 0 ]; then 523 | ERROR "Can't write into authorized_keys2 file '${authorized_keys2}'" 524 | return 1; 525 | fi 526 | 527 | for user in $( USERS_LIST ); do 528 | private_USER_AUTH_KEYS_ADD "${user}" "${authorized_keys2}" || return 1; 529 | done 530 | 531 | chown "${SSHGATE_GATE_ACCOUNT}" "${authorized_keys2}" 532 | chmod u+r "${authorized_keys2}" 533 | 534 | return 0; 535 | } 536 | 537 | # usage: USER_ACCEPTED_TOS 538 | # desc: returns 0 if has accepted the TOS, otherwise it returns 1 539 | USER_ACCEPTED_TOS () { 540 | local user= has_accepted= lang= tos_file= var= 541 | 542 | if [ $# -ne 1 ]; then 543 | BAD_ARGUMENTS ; return 1; 544 | fi 545 | 546 | user="$1" 547 | if [ ! -f "${SSHGATE_DIR_USERS}/${user}" ]; then 548 | ERROR "User '${user}' doesn't exist"; return 1; 549 | fi 550 | 551 | has_accepted=$( USER_GET_CONF "${user}" HAS_ACCEPT_TOS ) 552 | if [ "${has_accepted}" != 'true' ]; then 553 | lang=$( USER_GET_CONF "${user}" LANGUAGE ) 554 | [ -z "${lang}" ] && lang="${SSHGATE_DEFAULT_LANGUAGE}" 555 | # TODO: send a mail to the admin to tell there is no TOS file 556 | tos_file="${SSHGATE_DIR_TEMPLATES}/${lang}/${SSHGATE_TOS_FILENAME}" 557 | [ ! -r "${tos_file}" ] && tos_file="${SSHGATE_DIR_TEMPLATES}/us/${SSHGATE_TOS_FILENAME}" 558 | cat "${tos_file}"; BR 559 | ASK --yesno var "-> 'yes' / 'no' ?" 560 | [ "${var}" = 'N' ] && return 1; 561 | USER_SET_CONF "${user}" HAS_ACCEPT_TOS 'true' 562 | fi 563 | 564 | return 0; 565 | } 566 | 567 | fi # if [ "${__USER_FUNC__}" != 'Loaded' ]; then 568 | --------------------------------------------------------------------------------