# Initialize variables, if not set [ -z ${TMUX_SESSION_DIRS+x} ] && TMUX_SESSION_DIRS=( ~/.config/tmux/sessions ~/.local/share/tmux/sessions ~/.tmux/sessions) [ -z ${SETPROXY_CREDS_DIRS+x} ] && SETPROXY_CREDS_DIRS=(~/.config/proxycreds) [ -z ${KERBEROS_CONFIG_DIRS+x} ] && KERBEROS_CONFIG_DIRS=(~/.config/kinit) [ -z ${ENCFS_CONFIG_DIRS+x} ] && ENCFS_CONFIG_DIRS=(~/.config/encfs) export TMUX_SESSION_DIRS SETPROXY_CREDS_DIRS KERBEROS_CONFIG_DIRS promptcommandmunge () { ENTRY case ";${PROMPT_COMMAND};" in "*;$1;*") ;; *) if [ "$2" = "after" ] ; then PROMPT_COMMAND="${PROMPT_COMMAND};$1" else PROMPT_COMMAND="$1;${PROMPT_COMMAND}" fi esac EXIT } _ps1_hook() { local EXIT="$?" # This needs to be first PS1="" local RCol='\[\e[0m\]' local Red='\[\e[0;31m\]' local Gre='\[\e[0;32m\]' local BYel='\[\e[1;33m\]' local BBlu='\[\e[1;34m\]' local Pur='\[\e[0;35m\]' echo EXIT $EXIT if [ $EXIT != 0 ]; then PS1+="${Red}\u${RCol}" # Add red if exit code non 0 else PS1+="${Gre}\u${RCol}" fi PS1+="${RCol}@${BBlu}\h ${Pur}\W${BYel}$ ${RCol}" } _bashrc_tmp_hook() { if [ ! -z "${bashrctmp:-x}" ]; then if [ -n "${TMUX}" ]; then tmux set-environment bashrctmp "${bashrctmp}" fi fi } _pkcs11module_hook() { if [ ! -z ${SSH_TTY:+x} ]; then # Ich bin remote if [ -n "${P11M:+x}" ] then # komme ich über ssh, dann ist P11M (hoffentlich) gesetzt. Setze PKCS11_MODULE auf P11M logdebug "P11M set -> set PKCS11_MODULE to P11M" PKCS11_MODULE=${P11M} if [ -n "${TMUX}" ]; then tmux set-environment P11M ${P11M} tmux set-environment -g P11M ${P11M} fi fi else # Ich bin lokal if [ -z "${P11M:+x}" ] then # komme ich nicht über ssh, oder P11M ist nicht gesetzt, dann suche das P11-KIT-PROXY Modul für PKCS11_MODULE logdebug "P11M not set -> search for p11-kit-proxy" PKCS11_MODULE="$(whereis ${pkcs11_module_default:-p11-kit-proxy.so}|awk '{print $2}')" [ -n "$(whereis ${pkcs11_module_default:-p11-kit-proxy.so}|awk '{print $2}')" ] && \ export PKCS11_MODULE=$(whereis ${pkcs11_module_default:-p11-kit-proxy.so}|awk '{print $2}') || \ { loginfo "${pkcs11_module_default:-p11-kit-proxy.so} not forwarded by ssh or installed, unset P11M"; unset P11M; } else # komme ich über ssh, dann ist P11M (hoffentlich) gesetzt. Setze PKCS11_MODULE auf P11M logdebug "P11M set -> set PKCS11_MODULE to P11M" PKCS11_MODULE=${P11M} if [ -n "${TMUX}" ]; then tmux set-environment P11M ${P11M} tmux set-environment -g P11M ${P11M} fi fi fi loginfo "PKCS11_MODULE: $PKCS11_MODULE" if [ -n "${TMUX}" -a -n "${PKCS11_MODULE}" ]; then loginfo "set PKCS11_MODULE also in tmux environment" tmux set-environment PKCS11_MODULE ${PKCS11_MODULE} tmux set-environment -g PKCS11_MODULE ${PKCS11_MODULE} fi } function _remote_ssh_agent_hook () { if [ -e ~/.ssh/ssh_from_remote_auth_sock ] then logdebug "remote ssh-agent-socket exists" SSH_AUTH_SOCK_REMOTE=~/.ssh/ssh_from_remote_auth_sock source ~/.ssh/p11m else logdebug "remote ssh-agent-socket does not exists" unset SSH_AUTH_SOCK_REMOTE unset P11M fi } function _tmux_hook() { ## this function updates in combination with PROMPT_COMMAND the shell-environment-variables in tmux-sessions, # every time prompt is called. It does it only, when called from tmux (Environment TMUX is set) # [ -z "${TMUX+x}" ] || eval "$(tmux show-environment -s)" if [ -n "${TMUX:-}" ]; then eval "$(tmux show-environment -s)" fi } function _umask_hook { # To make the code more reliable on detecting the default umask # Record the default umask value on the 1st run [[ -z $DEFAULT_UMASK ]] && export DEFAULT_UMASK="$(builtin umask)" if [[ -n $UMASK ]]; then umask "$UMASK" else umask "$DEFAULT_UMASK" fi } function cpb() { scp "$1" ${SSH_CLIENT%% *}:~/Work } function sudo() { local SUDO local BASH local C SUDO=$( if [ -e /bin/sudo ]; then echo /bin/sudo; else echo /usr/bin/sudo; fi ) # [ -z "${SUDO} ] && "SUDO=$(command -v sudo) if $SSHS ; then logdebug "TEMPCONFIG" logdebug "\$1: $1" [ -e "$(which $1 2>/dev/null)" ] && C="x" logdebug "C: $C" [ getbashrcfile ] && BASH="bash --rcfile $(getbashrcfile)" || unset BASH logdebug "BASH1: $BASH" [ -z "${C:-x}" ] && unset BASH logdebug "BASH2: $BASH" unset BASH else logdebug "NO Tempconfig" unset BASH fi logdebug "SUDO: $SUDO" logdebug "BASH3: $BASH" logdebug "SHLVL: $SHLVL" logdebug "@: $@" [ -z "${C:-x}" ] && logwarn "run $1 -> $(which $1)" logdebug $SUDO \ GIT_AUTHOR_EMAIL="$GIT_AUTHOR_EMAIL" \ GIT_AUTHOR_NAME="$GIT_AUTHOR_NAME" \ GIT_COMMITTER_EMAIL="$GIT_COMMITTER_EMAIL" \ GIT_COMMITTER_NAME="$GIT_COMMITTER_NAME" \ TMUX="$TMUX" \ SSHS="$SSHS" \ P11M="$P11M" \ SSH_TTY="$SSH_TTY" \ SSH_AUTH_SOCK="$SSH_AUTH_SOCK" \ http_proxy="$http_proxy" \ $BASH \ $@ $SUDO \ GIT_AUTHOR_EMAIL="$GIT_AUTHOR_EMAIL" \ GIT_AUTHOR_NAME="$GIT_AUTHOR_NAME" \ GIT_COMMITTER_EMAIL="$GIT_COMMITTER_EMAIL" \ GIT_COMMITTER_NAME="$GIT_COMMITTER_NAME" \ TMUX="$TMUX" \ SSHS="$SSHS" \ P11M="$P11M" \ SSH_TTY="$SSH_TTY" \ SSH_AUTH_SOCK="$SSH_AUTH_SOCK" \ http_proxy="$http_proxy" \ $@ } create_symlinks() { #echo MSC_BASE: $MSC_BASE # MSC_BASEDIR="$1" # DIR="$(basename ${MSC_BASEDIR})" # cd "${MSC_BASEDIR}" [ -z "${MSC_GIT+x}" ] && MSC_GIT=git cd ${MSC_BASE} #echo "DIR MSC_BASEDIR $DIR $MSC_BASEDIR" git config credential.helper 'cache --timeout=300' #Anlegen von Symlinks rm -rf ~/.vimrc ~/.vim ~/bashrc_add ~/.gitconfig ~/.tmux.conf ~/.tmux ln -sf "${MSC_BASE}/vimrc" ~/.vimrc ln -sf "${MSC_BASE}/vim" ~/.vim ln -sf "${MSC_BASE}/.gitconfig" ~/.gitconfig ln -sf "${MSC_BASE}/.gitignore_global" ~/.gitignore_global #ln -sf "${MSC_BASE}/bashrc_add" ~/bashrc_add ln -sf "${MSC_BASE}/tmux" ~/.tmux ln -sf "${MSC_BASE}/tmux/tmux.conf" ~/.tmux.conf # Configure to use githooks in .githooks, not in standardlocation .git/hooks $MSC_GIT config core.hooksPath .githooks # remove all old symlinks in .githooks and relink files from .githooks to .git/hooks # don't know, why i do it here. TODO: Check it find .git/hooks -type l -exec rm {} \; && find .githooks -type f -exec ln -sf ../../{} .git/hooks/ \; cd ~- } setproxy () { # https://gist.github.com/yougg/5d2b3353fc5e197a0917aae0b3287d64 ENTRY local CONFIG case $# in 0) logwarning "too few arguments" return ;; *) if [ -z ${SETPROXY_CREDS_DIRS+x} ] ; then logwarning "are you sure, SETPROXY_CREDS_DIRS is defined?" return 1 else CONFIG=$(find ${SETPROXY_CREDS_DIRS[*]} -mindepth 1 -name "$1.conf" -print -quit 2>/dev/null ) NO_PROXY=$(find ${SETPROXY_CREDS_DIRS[*]} -mindepth 1 -name "no_proxy.conf" -print -quit 2>/dev/null ) fi ;; esac logwarning "CONFIG: ${CONFIG}" if [ -e ${CONFIG} ]; then logdebug -n "${CONFIG} existing: " source "${CONFIG}" loginfo "read $CONFIG" export PROXY_CREDS="$(urlencode ${PROXY_USER})${PROXY_PASS:+:}$(urlencode ${PROXY_PASS})" else loginfo "${CONFIG} not existing" # export PROXY_CREDS="" fi export {http,https,ftp,rsync,all}_proxy="${PROXY_PROTO:-http}://${PROXY_CREDS}${PROXY_CREDS:+@}${PROXY_SERVER}${PROXY_PORT:+:}${PROXY_PORT}" export {HTTP,HTTPS,FTP,RSYNC,ALL}_PROXY="${PROXY_PROTO:-http}://${PROXY_CREDS}${PROXY_CREDS:+@}${PROXY_SERVER}${PROXY_PORT:+:}${PROXY_PORT}" no_proxy="127.0.0.1,localhost" #no_proxy=$no_proxy,$(echo 10.{0..255}.{0..255}.{0..255}|tr ' ' ',') #no_proxy=$no_proxy,$(echo 172.{16..31}.{0..255}.{0..255}|tr ' ' ',') #no_proxy=$no_proxy,$(echo 192.168.{0..255}.{0..255}|tr ' ' ',') # no_proxy=${no_proxy}${PROXY_IGNORE:+,}${PROXY_IGNORE} # . $NO_PROXY export no_proxy git config -f ~/.gitconfig_local http.sslverify false git config -f ~/.gitconfig_local http.proxy $http_proxy git config -f ~/.gitconfig_local https.proxy $http_proxy # only for 'github.com' git config -f ~/.gitconfig_local http.https://github.com.proxy $http_proxy EXIT } unsetproxy () { ENTRY unset {HTTP,HTTPS,FTP,RSYNC,ALL}_PROXY unset PROXY_{CREDS,USER,PASS,SERVER,PORT,PROTO,IGNORE} unset {http,https,ftp,rsync,all}_proxy unset proxy_{creds,user,pass,server,port} unset no_proxy NO_PROXY git config -f ~/.gitconfig_local --unset http.proxy git config -f ~/.gitconfig_local --unset http.sslverify false git config -f ~/.gitconfig_local --unset https.proxy # git config -f ~/.gitconfig_local --unset core.sshCommand git config -f ~/.gitconfig_local --unset http.https://github.com.proxy EXIT } mencfs () { ENTRY [ $# -eq 0 ] && { logwarning "too few arguments" >&2; return 1; } local PKEY local ENCDIR local DESTDIR local PASS=$(command -v pass || exit 127 ) local ENCFS=$(command -v encfs || exit 127 ) local CONFIG if [ -z ${ENCFS_CONFIG_DIRS+x} ] ; then logwarning "are you sure, ENCFS_CONFIG_DIRS is defined?" EXIT return 1 else CONFIG=$(find ${ENCFS_CONFIG_DIRS[*]} -mindepth 1 -name "$1.conf" -print -quit 2>/dev/null ) fi if [ -e ${CONFIG} ]; then loginfo -n "${CONFIG} existing: " source "${CONFIG}" loginfo "sourced" else loginfo "${CONFIG} not existing" EXIT return 2 fi logdebug "ENCDIR: $ENCDIR" [ -z ${PKEY+x} ] && { EXIT; return 3; } [ -z ${ENCDIR+x} ] && { EXIT; return 4; } [ -z "${DESTDIR+x}" ] && [ -n "${XDG_RUNTIME_DIR}" ] && DESTDIR="${XDG_RUNTIME_DIR}/decrypted/$(basename $ENCDIR| tr '[:lower:]' '[:upper:]'| sed -e 's/^\.//')" [ -z ${DESTDIR+x} ] && DESTDIR="$(dirname $ENCDIR)/$(basename $ENCDIR| tr '[:lower:]' '[:upper:]'| sed -e 's/^\.//')" logdebug "DESTDIR: $DESTDIR" [ -d "$DESTDIR" ] || mkdir -p "$DESTDIR" $PASS "${PKEY}" 1>/dev/null 2>&1 || { logerr "entry $PKEY does not exist in passwordsotre"; return 5; } local ENCFS_PASSWORD=$($PASS show "${PKEY}"|head -n1) if [ -z ${ENCDIR+x} -a -d ${ENCDIR} ];then logerr "no encrypted directory found -> exit" EXIT return 4 else loginfo "mount encrypted directory $ENCDIR on $DESTDIR" $ENCFS -S $ENCDIR $DESTDIR < exit" >&2 EXIT return 128 else loginfo "umount encrypted directory" $1 >&2 sync $FUSERMOUNT -z -u "$1" fi else loginfo "no arguments given. Umount all mounted encfs-dirs" >&2 for i in $(mount|grep encfs|sed -e 's/^encfs on \(.*\)\ type.*$/\1/');do loginfo "$FUSERMOUNT -u $i" sync $FUSERMOUNT -z -u "$i" done EXIT return 1 fi EXIT } kinit-custom () { ENTRY local PKEY local REALM local PASS=$(command -v pass || exit 127 ) local KINIT=$(command -v kinit || exit 127 ) local CONFIG if [ -z ${KERBEROS_CONFIG_DIRS+x} ] ; then logwarning "are you sure, KERBEROS_CONFIG_DIRS is defined?" EXIT return 1 else CONFIG=$(find ${KERBEROS_CONFIG_DIRS[*]} -mindepth 1 -name "$1.conf" -print -quit 2>/dev/null ) fi if [ -e ${CONFIG} ]; then logdebug -n "${CONFIG} existing: " source "${CONFIG}" logdebug "sourced" else logwarning "${CONFIG} not existing" EXIT return 2 fi [ -z ${PKEY+x} ] && return 3 $PASS "${PKEY}" 1>/dev/null 2>&1 || return 3 logtrace "PKEY: ${PKEY}" local KERBEROS_PASSWORD="$($PASS show "${PKEY}"|head -n1)" local KERBEROS_USER="$($PASS "${PKEY}" | grep login | sed -e 's/^login: //' )" logdebug "$($PASS "${PKEY}" | grep login | sed -e 's/^login: //')" logtrace "KERBEROS_PASSWORD: ${KERBEROS_PASSWORD}" logdebug "KERBEROS_USER: ${KERBEROS_USER}" loginfo "Get kerberos-ticket for: $KERBEROS_USER@$REALM" if [ -z ${KERBEROS_USER:+x} ];then logwarning "no kerberos user found -> exit" EXIT return 4 else $KINIT -R "${KERBEROS_USER}@${REALM}" </dev/null | cut -d'/' -f1) echo MSC_GIT_REMOTE_NAME: $MSC_GIT_REMOTE_NAME MSC_BASE_PARENT="$(dirname $MSC_BASE)" if [ $1 == "localhost" ]; then CMD="" else local SSH="/usr/bin/ssh" [ -e ${MSC_BASE}/bashrc_add ] && $SSH -T -o VisualHostKey=no $@ "mkdir -p ~/\$MSC_BASE_PARENT; cat > ~/bashrc_add" < "${MSC_BASE}/bashrc_add" local CMD="$SSH -T $@" fi $CMD /bin/bash << EOF set -x [ -e /etc/bashrc ] && . /etc/bashrc [ -e /etc/bash.bashrc ] && . /etc/bash.bashrc echo "modify ~/.bashrc" sed -i -e '/^\[ -f bashrc_add \] /d' ~/.bashrc sed -i -e '/#MYSHELLCONFIG-start/,/#MYSHELLCONFIG-end/d' ~/.bashrc echo printf "%s\n" "#MYSHELLCONFIG-start" "[ -f \"\${HOME}/${MSC_SUBPATH}/bashrc_add\" ] && . \"\${HOME}/${MSC_SUBPATH}/bashrc_add\"" "#MYSHELLCONFIG-end"| tee -a ~/.bashrc #printf "%s\n" "#MYSHELLCONFIG-start" "if [ -e \${HOME}/${MSC_SUBPATH}/bashrc_add ]; then" " . \${HOME}/${MSC_SUBPATH}/bashrc_add;" "else" " if [ -f ~/bashrc_add ] ;then" " . ~/bashrc_add;" " fi;" "fi" "#MYSHELLCONFIG-end" |tee -a ~/.bashrc echo echo cleanup from old config rm -rf ~/server-config && echo rm -rf ~/server-config echo mkdir -p ~/.local mkdir -p ~/.local echo git clone --recurse-submodules $(git remote get-url $MSC_GIT_REMOTE_NAME) \${HOME}/${MSC_SUBPATH} git clone --recurse-submodules $(git remote get-url $MSC_GIT_REMOTE_NAME) \${HOME}/${MSC_SUBPATH} date "+%s" > \${HOME}/${MSC_SUBPATH}/.last_update_submodules # date "+%s" > \${HOME}/${MSC_SUBPATH}/.last_update_repo EOF EXIT } [ -e ${MSC_BASE}/sshs ] && source ${MSC_BASE}/sshs [ -z ${VIMRC+x} ] &&VIMRC="${MSC_BASE}/vimrc" svi () { ENTRY if [ -f ${VIMRC} ]; then sudo vim -u "${VIMRC}" $@; else sudo vim $@ fi EXIT } #vim-plugins-update () { # ENTRY # vim -c "PluginUpdate" -c ":qa!" # EXIT # #} # #vim-plugins-install () { # ENTRY # vim -c "PluginInstall" -c ":qa!" # EXIT # #} vim-repair-vundle () { ENTRY if [ -z ${MSC_BASE+x} ]; then echo "MSC_BASE nicht gesetzt. Eventuell noch einmal ausloggen und wieder einloggen" else cd $MSC_BASE cd vim/bundle rm -rf Vundle.vim echo git clone "${MSC_GIT_SUBMODULES_SERVER-$MSC_GIT_SUBMODULES_SERVER_DEFAULT}gmarik/Vundle.vim.git" git clone "${MSC_GIT_SUBMODULES_SERVER-$MSC_GIT_SUBMODULES_SERVER_DEFAULT}gmarik/Vundle.vim.git" cd ~- fi EXIT } getbashrcfile () { ENTRY if [ -z ${BASHRC+x} ] ; then loginfo "bash uses default" return 1 else cat /proc/$$/cmdline | xargs -0 echo|awk '{print $3}' fi EXIT } catbashrcfile () { ENTRY if [ -z ${BASHRC+x} ] ; then loginfo "bash uses default" return 1 else cat $(getbashrcfile) fi EXIT } vibashrcfile () { ENTRY if [ -z ${BASHRC+x} ] ; then loginfo "bash uses default" return 1 else vi $(getbashrcfile) fi EXIT } getvimrcfile () { ENTRY if [ -z ${VIMRC+x} ] ; then echo "vim uses default" >&2 else echo $VIMRC fi EXIT } catvimrcfile () { ENTRY if [ -z ${VIMRC+x} ] ; then echo "vim uses default" >&2 else #cat $VIMRC cat $(getvimrcfile) fi EXIT } vivimrcfile () { ENTRY if [ -z ${VIMRC+x} ] ; then echo "vim uses default" >&2 else vi $(getvimrcfile) fi EXIT } # Functions to set the correct title of the terminal function title() { ENTRY # change the title of the current window or tab echo -ne "\033]0;$*\007" EXIT } function sshx() { /usr/bin/ssh "$@" # revert the window title after the ssh command title $USER@$HOST } function su() { /bin/su "$@" # revert the window title after the su command title $USER@$HOST } function usage() { cat << EOF Keyboard-shortcuts: # tmux: C+Cursor tmux window change size M+[hjkl] tmux change splitted windows # vim: C+[hjkl] vim change splitted windows EOF } function update-hetzner-serverlist() { for i in basic-services sc xe tu fe; do echo "Retrieve servers for ${i}" curl -s -H "Authorization: Bearer $(pass show hetzner.com/projects/${i}/api-token)" \ https://api.hetzner.cloud/v1/servers \ | /usr/bin/jq '.servers[].public_net.ipv4.ip'|sed -e 's/\"//g' \ |while read i; do dig -x $i | awk '$0 !~ /^;/ && $4 == "PTR" {print $5}' done |sed -s -e 's/\.$//' > ~/.dsh/group/hetzner-servers-${i} done cat ~/.dsh/group/hetzner-servers-* > ~/.dsh/group/hetzner-servers } function tmuxx() { ENTRY case $# in 1) SESS=($(find ${TMUX_SESSION_DIRS[*]} -mindepth 1 -name "$1.session" 2>/dev/null )) ;; *) logwarning no session specified return ;; esac TMUX_BIN='/usr/bin/tmux' $TMUX_BIN -f ~/.tmux.conf new-session -d [ -e ${SESS[0]} ] && $TMUX_BIN source-file ${SESS[0]} $TMUX_BIN attach-session -d EXIT } function checkbkp() { ENTRY if ping -c 3 backup >/dev/null 2>&1 ; then local SSH="/usr/bin/ssh" local CMD="$SSH -T root@backup" $CMD /bin/bash << EOF sudo find /srv/nfs/backup -mindepth 1 -maxdepth 1|grep -v -e "git$\|git-backup-repos"|while read i;do printf "%-30s%s\\n" "\$i" \$(ls \$i|tail -n1);done|sort -k 2.1 -r EOF else echo "backup is not reachable -> exit" return 1 fi EXIT } function checkbkp-full() { ENTRY if ping -c 3 backupn >/dev/null 2>&1 ; then local SSH="/usr/bin/ssh" local CMD="$SSH -T root@backup" $CMD /bin/bash << EOF sudo find /srv/nfs/backup -mindepth 1 -maxdepth 1|grep -v -e "git$\|git-backup-repos"|while read i;do printf "%-30s%s\\n" "\$i" \$(ls \$i|tail -n1);done|sort -k 2.1 -r EOF command -v pdsh && pdsh -g vpn sudo systemctl status backup.service else logwarning "backup is not reachable -> exit" return 1 fi EXIT } turnoffbeep() { ENTRY changebeep none EXIT } changebeep() { ENTRY local style case $1 in none) style=none ;; visible) style=visible ;; audible) style=audible ;; *) logwarning "usage: changebeep [none|visible|audible]" EXIT return 1 ;; esac local line='set bell-style' local file=~/.inputrc if [ -e "${file}" ] ; then sed -i -e "/$line/d" "${file}" fi echo "${line} ${style}" >> "${file}" return 0 EXIT } turnoffconfigsync() { ENTRY local line='MSC_GIT_SYNC=' local file=~/.bashrc if [ -e "${file}" ] ; then sed -i -e "/${line}/d" "${file}" fi sed -i -e "/#MYSHELLCONFIG-start/i${line}false" "${file}" EXIT } turnonconfigsync() { ENTRY local line='MSC_GIT_SYNC=' local file=~/.bashrc if [ -e "${file}" ] ; then sed -i -e "/${line}/d" "${file}" fi sed -i "/#MYSHELLCONFIG-start/i${line}true" "${file}" EXIT } function gnome-shell-extensions-enable-defaults() { ENTRY local i if [ -f ~/.config/gnome-shell-extensions-default.list ]; then for i in $(cat ~/.config/gnome-shell-extensions-default.list); do #gnome-shell-extension-tool -e $i; gnome-extensions enable $i; done; fi EXIT } gnome-shell-extensions-make-actual-permanent() { ENTRY file="${HOME}/.config/gnome-shell-extensions-default.list" local EXTENSIONS=$(gsettings get org.gnome.shell enabled-extensions) line="[org/gnome/shell]" for line in ${EXTENSIONS[@]}; do loginfo "add $line to $file" grep -xqF -- ${line} ${file} || echo $line >> $file done EXIT } gnome-shell-extensions-make-actual-permanent-systemwide() { ENTRY # https://people.gnome.org/~pmkovar/system-admin-guide/extensions-enable.html # https://askubuntu.com/questions/359958/extensions-are-turned-off-after-reboot local file="/etc/dconf/profile/user" sudo mkdir -p "/etc/dconf/profile/" local line='user-db:user' if [ -e "${file}" ] ; then command="grep -xqF -- ${line} ${file} || echo $line >> $file" logtrace "$command" sudo sh -c "$command" fi local line='system-db:local' if [ -e "${file}" ] ; then command="grep -xqF -- ${line} ${file} || echo $line >> $file" logtrace "$command" sudo sh -c "$command" fi local line='enabled-extensions=' local file='/etc/dconf/db/local.d/00-extensions' sudo mkdir -p '/etc/dconf/db/local.d' if [ -e "${file}" ] ; then sudo sed -i -e "/${line}/d" "${file}" #sudo sed -i -e "/\[org\/gnome\/shell\]/d" "${file}" fi local EXTENSIONS=$(gsettings get org.gnome.shell enabled-extensions) line="[org/gnome/shell]" command="grep -xqF -- ${line} ${file} || echo $line >> $file" sudo sh -c "$command" local line='enabled-extensions=' loginfo "Update or add extensions" #echo "${line}${EXTENSIONS}" | sudo tee -a "${file}" sudo sed -i "/\[org\/gnome\/shell\]/a${line}${EXTENSIONS}" "${file}" sudo dconf update EXIT } reachable-default () { local SERVER=$1 local PORT=${2:-22} local res=3 nc=$(command -v nc || resturn 2) # if which nc >/dev/null; then if nc -w 2 -z $SERVER $PORT 2>/dev/null; then # res=0 return 0 fi # else # res=2 # fi # return $res } reachable () { ENTRY # returncodes: # 1: servername not resolveable # 2: command nc not found # 3: server:port not reachable # 999999: something went wrong # 0: server was resolve- and reachable GETENTHOSTS=ahosts local SERVER=$1 # dig does not consult /etc/hosts, so use getent hosts instead #local IP=$(dig +nocmd $SERVER a +noall +answer|tail -n 1 |awk '{print $5}') # getent ahostsv4 returns only ipv4 addresses loginfo -n "Try to resolve $SERVER: " local IP=$(getent $GETENTHOSTS $SERVER|awk '$0 ~ /STREAM/ {print $1}'|uniq|head -n1) if [ -z ${IP-x} ]; then logwarning "not resolvable -> exit" return 1 else loginfo $IP fi local PORT=${2:-22} local SEC=${3:-1} local res=999 local i loginfo -n "Try to connect to ${SERVER} (${IP}):${PORT} " >&2 for i in $(seq 1 $SEC); do loginfo -n "." >&2 if reachable-default ${IP} ${PORT} 2>/dev/null; then res=0 break else res=$? fi [ ${SEC} -gt 1 -a $i -lt ${SEC} ] && sleep 1 done [ ${res} -gt 0 ] && loginfo " not reachable" >&2 || loginfo " success" >&2; EXIT return $res } utoken () { ENTRY ssh_identity=$1 [ -z "${PKCS11_MODULE+x}" ] && { PKCS11_MODULE=$P11M; export PKCS11_MODULE; } logdebug "PKCS11_MODULE=${PKCS11_MODULE:-undefined}" if [ -n "${ssh_identity+x}" ]; then agentfile="${HOME}/.ssh/agents/agent-${ssh_identity}-$(hostname)" if [ -e "$agentfile" ]; then local SSH_AUTH_SOCK local SSH_AGENT_PID /bin/sh -c ". $agentfile >/dev/null 2>/dev/null; ssh-add -l; ssh-add -e $PKCS11_MODULE; ssh-add -l" fi fi EXIT } token(){ [ -z "${PKCS11_MODULE:+x}" -a -n "{P11M:-x}" ] && { PKCS11_MODULE=$P11M; export PKCS11_MODULE; } loginfo "SSH_AUTH_SOCK=${SSH_AUTH_SOCK:-unset}" loginfo "PKCS11_MODULE=${PKCS11_MODULE:-unset}" # If DISPLAY is set, ssh-add calls ssh-askpass, and if its in remote-terminal, it wont work # So remember and unset DISPLAY, and set it at the end again, if it was set before [ $DISPLAY ] && local DISPLAY_ORIG=$DISPLAY [ $DISPLAY ] && logtrace "unset DISPLAY: $DISPLAY" [ $DISPLAY ] && unset DISPLAY # Write public keys of all in agent stored keys to a temporary file local tmppubkey="$(mktemp -p ${XDG_RUNTIME_DIR} pubkey.XXXXXX.pub)" logtrace "tmppubkey: $tmppubkey" loginfo "$(ssh-add -L > $tmppubkey)" # Check if public-keys in tmppubkey are working. They are not working, if you removed and add back hardware-token. loginfo "$(ssh-add -T ${tmppubkey}|| { ssh-add -e $PKCS11_MODULE; ssh-add -s $PKCS11_MODULE; } )" logdebug "$(rm "${tmppubkey}")" loginfo "$(ssh-add -l )" [ $DISPLAY_ORIG ] && logtrace "reset DISPLAY=$DISPLAY_ORIG" [ $DISPLAY_ORIG ] && export DISPLAY=$DISPLAY_ORIG } token-extract-pubkey() { _pkcs11module_hook if pkcs11-tool --module $PKCS11_MODULE --list-token-slots >&2 ;then ssh-keygen -i -m pkcs8 -f <(pkcs11-tool --module $PKCS11_MODULE -r --type pubkey ${1:+--label} ${1} |openssl rsa -pubin -inform DER ) if [ $? -gt 0 ] ; then token-list-objects >&2 fi else echo "Please insert token. Exit" >&2 return 1 fi } token-list-objects() { [ -z "${PKCS11_MODULE+x}" ] && { PKCS11_MODULE=$P11M; export PKCS11_MODULE; } case $1 in --login|-l) pkcs11-tool --module $PKCS11_MODULE --login --list-objects ;; *) pkcs11-tool --module $PKCS11_MODULE --list-objects ;; esac } loadagent() { ENTRY local af af=$(startagent --create-only $1 ) loginfo "Load agent from $af" unset SSH_AUTH_SOCK SSH_AGENT_PID PKCS11_MODULE [ -n "${af:+x}" ] && eval $(<$af) if which tmux 1>/dev/null 2>&1 then [ -n "${SSH_AUTH_SOCK:-}" ] && tmux set-environment SSH_AUTH_SOCK $SSH_AUTH_SOCK || tmux set-environment -r SSH_AUTH_SOCK [ -n "${SSH_AGENT_PID:-}" ] && tmux set-environment SSH_AGENT_PID $SSH_AGENT_PID || tmux set-environment -r SSH_AGENT_PID [ -n "${PKCS11_MODULE:-}" ] && tmux set-environment PKCS11_MODULE $PKCS11_MODULE || tmux set-environment -r PKCS11_MODULE fi logdebug "SSH_AUTH_SOCK: ${SSH_AUTH_SOCK-not set}" logdebug "SSH_AGENT_PID: ${SSH_AGENT_PID-not set}" logdebug "PCKS11_MODULE: ${PCKS11_MODULE-not set}" loginfo "currently loaded keys in agent: $(ssh-add -l)" EXIT } setloglevel () { ENTRY local loglevels local oldloglevel=${LOGLEVEL-$LOGLEVEL_DEFAULT} declare -a loglevels loglevels=("ERROR" "WARN" "INFO" "DEBUG" "TRACE") if [[ ${loglevels[*]} =~ "${1^^}" ]]; then export LOGLEVEL=${1^^} else logerr "LOGLEVEL must be one of ERROR, WARN, INFO, DEBUG or TRACE" fi logerr "change LOGLEVEL from $oldloglevel -> $LOGLEVEL" EXIT } setfileloglevel () { ENTRY local loglevels local oldloglevel=${FILELOGLEVEL-${FILELOGLEVEL_DEFAULT}} declare -a loglevels loglevels=("ERROR" "WARN" "INFO" "DEBUG" "TRACE") if [[ ${loglevels[*]} =~ "$1" ]]; then export FILELOGLEVEL=$1 else logerr "FILELOGLEVEL must be one of ERROR, WARN, INFO, DEBUG or TRACE" fi logerr "change FILELOGLEVEL from $oldloglevel -> $FILELOGLEVEL" EXIT } getloglevels () { ENTRY cat << EOF |tee -a $SCRIPT_LOG LOGLEVEL: ${LOGLEVEL-${LOGLEVEL_DEFAULT}} FILELOGLEVEL: ${FILELOGLEVEL-${FILELOGLEVEL_DEFAULT}} change LOGLEVEL: \$ setloglevel [ERROR|WARN|INFO|DEBUG|TRACE] change FILELOGLEVEL: \$ setfileloglevel [ERROR|WARN|INFO|DEBUG|TRACE] EOF } rescan_scsi () { echo "- - -" > /sys/class/scsi_host/host0/scan } get_crtime() { for target in "${@}"; do inode=$(stat -c %i "${target}") fs=$(df --output=source "${target}" | tail -1) crtime=$(sudo debugfs -R 'stat <'"${inode}"'>' "${fs}" 2>/dev/null | grep -oP 'crtime.*--\s*\K.*') printf "%s\t%s\n" "${target}" "${crtime}" done } is_btrfs_subvolume() { sudo btrfs subvolume show "$1" >/dev/null } convert_to_subvolume () { local XSUDO local DIR case $1 in --sudo|-s) XSUDO=sudo shift ;; esac DIR="${1}" [ -d "${DIR}" ] || return 1 is_btrfs_subvolume "${DIR}" && return 0 set -x #btrfs subvolume create "${DIR}".new && \ ${XSUDO:+sudo} btrfs subvolume create "${DIR}.new" && \ /bin/cp -aTr --reflink=always "${DIR}" "${DIR}".new && \ mv "${DIR}" "${DIR}".orig && \ mv "${DIR}".new "${DIR}" || return 2 set +x return 0 } cporig () { cp -b -i "${1}" "${1}.orig" } vgrename_full () { altevolumegroup="$1" neuevolumegroup="$2" vgrename ${altevolumegroup} ${neuevolumegroup} sed -i "s/${altevolumegroup}/${neuevolumegroup}/g" /etc/fstab sed -i "s/${altevolumegroup}/${neuevolumegroup}/g" /boot/grub/grub.cfg sed -i "s/${altevolumegroup}/${neuevolumegroup}/g" /boot/grub/menu.lst sed -i "s/${altevolumegroup}/${neuevolumegroup}/g" /etc/initramfs-tools/conf.d/resume update-initramfs -c -k all } getfreeip () { local N=$1 nmap -v -sn -n ${N} -oG - | awk '/Status: Down/{print $2}' } getusedip () { local N=$1 local DNS=$2 nmap -v -sn -n $1 -oG - | awk '!/Status: Down/{print $2}'|while read i;do echo "$i: $(dig ${DNS:+@}${DNS:-} -x $i +short +search)" done } getips () { local N=$1 local DNS=$2 nmap -v -sn -n $1 -oG - | while read i do j=$(echo "$i"|awk '{print $2}') case $i in *Status:\ Down*) echo "$j: $(dig ${DNS:+@}${DNS:-} -x $j +short +search)" ;; *Status:\ Up*) echo "$j:" ;; esac done } function getdbcreds_jra () { local APP_INST=/opt/atlassian/jira local JRA_HOME=$(awk -F "=" '/jira.home/ {gsub(/ /, "", $0); print $2}' "${APP_INST}/atlassian-jira/WEB-INF/classes/jira-application.properties") local DB_FILE="${JRA_HOME}/dbconfig.xml" if xmllint --version >/dev/null 2>&1; then DB_URL="$(xmllint --xpath "jira-database-config/jdbc-datasource/url/text()" ${DB_FILE})" DB_USER="$(xmllint --xpath "jira-database-config/jdbc-datasource/username/text()" ${DB_FILE})" DB_PWD="$(xmllint --xpath "jira-database-config/jdbc-datasource/password/text()" ${DB_FILE})" else echo "please install xmllint »apt install libxml2-utils«" DB_URL="$(grep -oPm1 "(?<=)[^<]+" ${DB_FILE})" DB_USER="$(grep -oPm1 "(?<=)[^<]+" ${DB_FILE})" DB_PWD="$(grep -oPm1 "(?<=)[^<]+" ${DB_FILE})" fi DB_HOST="$(echo $DB_URL|sed 's@^.*//@@;s@\(^.*\):\(.*\)/\(.*\)$@\1@')" DB_PORT="$(echo $DB_URL|sed 's@^.*//@@;s@\(^.*\):\(.*\)/\(.*\)$@\2@')" DB_NAME="$(echo $DB_URL|sed 's@^.*//@@;s@\(^.*\):\(.*\)/\(.*\)$@\3@')" return 0 } function getdbcreds_cnf () { local APP_INST=/opt/atlassian/confluence local CNF_HOME=$(awk -F "=" '/confluence.home/ {gsub(/ /, "", $0); print $2}' "${APP_INST}/confluence/WEB-INF/classes/confluence-init.properties") local DB_FILE="${CNF_HOME}/confluence.cfg.xml" if xmllint --version >/dev/null 2>&1; then DB_URL="$(xmllint --xpath "confluence-configuration/properties/property[@name='hibernate.connection.url']/text()" ${DB_FILE})" DB_USER="$(xmllint --xpath "confluence-configuration/properties/property[@name='hibernate.connection.username']/text()" ${DB_FILE})" DB_PWD="$(xmllint --xpath "confluence-configuration/properties/property[@name='hibernate.connection.password']/text()" ${DB_FILE})" else echo "please install xmllint »apt install libxml2-utils«" DB_URL="$(grep -oPm1 "(?<=)[^<]+" ${DB_FILE})" DB_USER="$(grep -oPm1 "(?<=)[^<]+" ${DB_FILE})" DB_PWD="$(grep -oPm1 "(?<=)[^<]+" ${DB_FILE})" fi DB_HOST="$(echo $DB_URL|sed 's@^.*//@@;s@\(^.*\):\(.*\)/\(.*\)$@\1@')" DB_PORT="$(echo $DB_URL|sed 's@^.*//@@;s@\(^.*\):\(.*\)/\(.*\)$@\2@')" DB_NAME="$(echo $DB_URL|sed 's@^.*//@@;s@\(^.*\):\(.*\)/\(.*\)$@\3@')" #cd - return 0 } function connectdbpostgres () { case $HOSTNAME in *jra*|*jira*) getdbcreds_jra $2 ;; *cnf*|*confapp*) getdbcreds_cnf $2 ;; *) echo "wrong argument" return 1 ;; esac DB_USER=postgres read -p "Password for user ${DB_USER} on ${DB_HOST}: " DB_PWD cat << EOF connect to ${DB_HOST}:${DB_PORT} with user: ${DB_USER} and passwd: ${DB_PWD} EOF PGPASSWORD=$DB_PWD psql -h $DB_HOST -p $DB_PORT -U postgres } function connectdb () { case $HOSTNAME in *jra*|*jira*) getdbcreds_jra $2 ;; *cnf*|*confapp*) getdbcreds_cnf $2 ;; *) echo "wrong argument" >&2 return 1 ;; esac cat << EOF >&2 connect to ${DB_HOST}:${DB_PORT}/${DB_NAME} with user: ${DB_USER} and passwd: ${DB_PWD:+********} EOF if [ $# -gt 0 ] then case $1 in -c) shift PGPASSWORD=$DB_PWD psql -h $DB_HOST -p $DB_PORT -U $DB_USER $DB_NAME -c "$@" ;; *) PGPASSWORD=$DB_PWD psql -h $DB_HOST -p $DB_PORT -U $DB_USER $DB_NAME $@ ;; esac else PGPASSWORD=$DB_PWD psql -h $DB_HOST -p $DB_PORT -U $DB_USER $DB_NAME fi } urlencode() { python3 -c "import sys; from urllib.parse import quote; print(quote(sys.argv[1]));" "$@"; } urldecode() { python3 -c "import sys; from urllib.parse import unquote; print(unquote(sys.argv[1]));" "$@"; } urlencodeplus() { python3 -c "import sys; from urllib.parse import quote_plus; print(quote_plus(sys.argv[1]));" "$@"; } urldecodeplus() { python3 -c "import sys; from urllib.parse import unquote_plus; print(unquote_plus(sys.argv[1]));" "$@"; } findlocallogins() { last -F -a $(for i in $(find /var/log -maxdepth 1 -name "wtmp*"|sort -h);do echo -n "-f $i ";done)|grep -v "pts/\|reboot\|wtmp"|awk '{print $4,$5,$7}'|uniq } getjrahomes() { local APP_INST=/opt/atlassian/jira APP_HOME=$(awk -F "=" '/^jira.home/ {gsub(/ /, "", $0); print $2}' "${APP_INST}/atlassian-jira/WEB-INF/classes/jira-application.properties") [ -e "${APP_HOME}/cluster.properties" ] \ && APP_SHARED_HOME=$(awk -F "=" '/^jira.shared.home/ {gsub(/ /, "", $0); print $2}' "${APP_HOME}/cluster.properties") } getcnfhomes() { xmllint --version >/dev/null 2>&1 || { echo "please install xmllint »apt install libxml2-utils«" >&2; return 1; } local APP_INST=/opt/atlassian/confluence APP_HOME="$(awk -F "=" '/^confluence.home/ {gsub(/ /, "", $0); print $2}' "${APP_INST}/confluence/WEB-INF/classes/confluence-init.properties" )" [ -e "${APP_HOME}/confluence.cfg.xml" ] \ && APP_SHARED_HOME="$(xmllint --xpath "confluence-configuration/properties/property[@name='confluence.cluster.home']/text()" "${APP_HOME}/confluence.cfg.xml" 2>/dev/null)" } getatsvc() { case $HOSTNAME in *jra*|*jira*) export SVC=jra; export APP_NAME=jira export APP_INST_NAME=atlassian-jira export APP_LOG_DIR=log getjrahomes ;; *cnf*|*confapp*) export SVC=cnf; export APP_NAME=confluence export APP_INST_NAME=confluence export APP_LOG_DIR=logs getcnfhomes ;; esac case ${HOSTNAME} in sl[etp]*) export PTE=${HOSTNAME:2:1} ;; esac } goathome() { getatsvc [ "${APP_HOME:-x}" == "x" ] && { echo no $SVC home configured >&2; return 127; } cd "${APP_HOME}" } goatshome() { getatsvc [ "${APP_SHARED_HOME:-x}" == "x" ] && { echo no $SVC home configured >&2; return 127; } cd "${APP_SHARED_HOME}" } gojrahome() { getjrahomes [ "${APP_HOME:-x}" == "x" ] && { echo no jira home configured >&2; return 127; } cd "${APP_HOME}" } gojrashome() { getjrahomes [ "${APP_SHARED_HOME:-x}" == "x" ] && { echo no jira shared-home configured >&2; return 127; } cd "${APP_SHARED_HOME}" } gocnfhome() { getcnfhomes [ "${APP_HOME:-x}" == "x" ] && { echo no confluence home configured >&2; return 127; } cd "${APP_HOME}" } gocnfshome() { getcnfhomes [ "${APP_SHARED_HOME:-x}" == "x" ] && { echo no confluence shared-home configured >&2; return 127; } cd "${APP_SHARED_HOME}" } setserver() { export sshcon="$@" if [ -n "${TMUX}" ]; then tmux set-environment sshcon "$@" fi } setgitremote() { cd ~/.local/myshellconfig git remote get-url ${MSC_GIT_REMOTE_NAME:-$MSC_GIT_REMOTE_NAME_DEFAULT} >/dev/null 2>&1 case $? in 2) git remote add ${MSC_GIT_REMOTE_NAME:-$MSC_GIT_REMOTE_NAME_DEFAULT} ${MSC_GIT_PULLURL:-$MSC_GIT_PULLURL_DEFAULT} git fetch ${MSC_GIT_REMOTE_NAME:-$MSC_GIT_REMOTE_NAME_DEFAULT} ;; *) echo "no error getting remote url" ;; esac git remote set-url ${MSC_GIT_REMOTE_NAME:-$MSC_GIT_REMOTE_NAME_DEFAULT} ${MSC_GIT_PULLURL:-$MSC_GIT_PULLURL_DEFAULT} # sequence for push-url # configured pushurl from .bashrc # configured pullurl from .bashrc (if no pushrul is defined and pushurl is the same as pullurl) # default pushurl (if no push or pullurl is defined in .bashrc) # default pullurl (if no push/pull/default_pushurl is defined, then default pushurl is the same as default pullurl) git remote set-url --push ${MSC_GIT_REMOTE_NAME:-$MSC_GIT_REMOTE_NAME_DEFAULT} \ ${MSC_GIT_PUSHURL:-${MSC_GIT_PULLURL:-${MSC_GIT_PUSHURL_DEFAULT:-$MSC_GIT_PULLURL_DEFAULT}}} git branch -u "${MSC_GIT_REMOTE_NAME:-$MSC_GIT_REMOTE_NAME_DEFAULT}"/"${MSC_GIT_BRANCH:-$MSC_GIT_BRANCH_DEFAULT}" git checkout ${MSC_GIT_BRANCH:-$MSC_GIT_BRANCH_DEFAULT} loginfo "now remotes are: $(git remote -v)" loginfo "new upstream set to: $(git branch -vv)" git fetch -p git merge FETCH_HEAD git submodule sync git submodule update --init --recursive --remote } pg_drop_and_recreate_db () { DB=$1 DBHOST=localhost case ${DB} in jra*) PORT=5532 ;; cnf*) PORT=5432 ;; *) return 1 ;; esac # DROP and recreate adatabase in PG12 jira psql -h$DBHOST -p $PORT -U postgres \c postgres DROP DATABASE ${DB}; CREATE DATABASE ${DB} OWNER ${DB}; REVOKE CONNECT,TEMPORARY ON DATABASE ${DB} FROM PUBLIC; \c ${DB} REVOKE ALL ON SCHEMA public FROM ${DB}; REVOKE ALL ON SCHEMA public FROM public; ALTER SCHEMA public OWNER TO ${DB}; GRANT ALL ON SCHEMA public TO ${DB}; \dn+ \l+ ${DB} \c postgres } scppvp () { local SERVICE local SVC case $1 in confluence|cnf) SERVICE=confluence SVC=cnf ;; jira|jra) SERVICE=jira SVC=jra ;; esac echo SVC: $SVC echo SERVICE: $SERVICE local SETTINGS="$(ls -t $HOME/git/bmi/at.gv.bmi.common.pvp.settings/target/at.gv.bmi.atlassian.pvp-settings*|head -n1)" local PVPAUTH="$(ls -t ${HOME}/git/bmi/at.gv.bmi.${SERVICE}.pvp.authenticator/target/at.gv.bmi.atlassian.pvp-authenticator*${SVC}*|head -n1)" cat << EOF deploy ${SERVICE} SETTINGS: ${SETTINGS} PVP Authenticator: ${PVPAUTH} EOF parallel-scp -h ${HOME}/.dsh/group/${SERVICE} ${SETTINGS} ${PVPAUTH} /root/INSTALL } function goarchive () { local SHOPTEXTGLOB="$(shopt -p |grep extglob)" shopt -s extglob if [ "${#:-0}" -gt 0 ] then case "$1" in -h) cat << EOF Usage: goarchive goarchive [0-9][0-9]* goarchive [YYYY-MM-DD] if used without argument, change to $(xdg-user-dir ARCHIVE) if argument is an positive integer, go number of snapshots back (see a list of possible snapshots) if argument is [YYYY-MM-DD], go to snapshot from date EOF ;; [0-9]*) ardir="$(xdg-user-dir ARCHIVE)/$(ls $(xdg-user-dir ARCHIVE) |tail -n${1:-1}|head -n1)" cat << EOF last few archives: $(ls $(xdg-user-dir ARCHIVE) | \ tail -n $(( ${1:-1} * 2 )) | \ while read i;do if [ "${i}" = "$(basename ${ardir})" ]; then printf " * %s <- chosen\n" "$i"; else printf " %s\n" "$i";fi;done) EOF ;; *) ardir="$(xdg-user-dir ARCHIVE)/${1}" ;; esac [ -e ${ardir} ] && cd ${ardir} else [ -e "$(xdg-user-dir ARCHIVE)" ] && cd "$(xdg-user-dir ARCHIVE)" fi # shopt -u extglob eval $SHOPTEXTGLOB } # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ # # EXESUDO # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ # # # Purpose: # -------------------------------------------------------------------- # # Execute a function with sudo # # Params: # -------------------------------------------------------------------- # # $1: string: name of the function to be executed with sudo # # Usage: # -------------------------------------------------------------------- # # exesudo "funcname" followed by any param # # -------------------------------------------------------------------- # # Created 01 September 2012 Last Modified 02 September 2012 function exesudo () { ### ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ## # # LOCAL VARIABLES: # ### ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ## # # I use underscores to remember it's been passed local _funcname_="$1" local params=( "$@" ) ## array containing all params passed here local tmpfile="/dev/shm/$RANDOM" ## temporary file local content ## content of the temporary file local regex ## regular expression ### ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ## # # MAIN CODE: # ### ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ## # # WORKING ON PARAMS: # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ # # Shift the first param (which is the name of the function) unset params[0] ## remove first element # params=( "${params[@]}" ) ## repack array # # WORKING ON THE TEMPORARY FILE: # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ content="#!/bin/bash\n\n" # # Write the params array content="${content}params=(\n" regex="\s+" for param in "${params[@]}" do if [[ "$param" =~ $regex ]] then content="${content}\t\"${param}\"\n" else content="${content}\t${param}\n" fi done content="$content)\n" echo -e "$content" > "$tmpfile" # # Append the function source echo "#$( type "$_funcname_" )" >> "$tmpfile" # # Append the call to the function echo -e "\n$_funcname_ \"\${params[@]}\"\n" >> "$tmpfile" # # DONE: EXECUTE THE TEMPORARY FILE WITH SUDO # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ sudo bash "$tmpfile" rm "$tmpfile" } if ${SSHS-false} then echo declare tsudo tsudo () { [ $(id -u) -gt 0 ] && return 1 [ $# -eq 0 ] && return 2 local u_id="$(id -u $1)" local g_id="$(id -g $1)" local b_rc=$(getbashrcfile) local v_rc=$(getvimrcfile) install -d -o ${u_id} -g ${g_id} -m 0700 /run/user/${u_id} local bashrctmp="/tmp/$(basename ${b_rc})" local vimrctmp="/tmp/$(basename ${v_rc})" [ -n "${getbashrcfile:-x}" ] && install -o ${u_id} -g ${g_id} -T ${b_rc} "${bashrctmp}" [ -n "${getvimrcfile:-x}" ] && install -o ${u_id} -g ${g_id} -T ${v_rc} "${vimrctmp}" sed -i -e 's;\(bashrctmp=\)\(.*$\);\1'${bashrctmp}';' $bashrctmp sed -i -e 's;\(vimrctmp=\)\(.*$\);\1'${vimrctmp}';' $bashrctmp sudo -u ${1} /bin/bash --rcfile ${bashrctmp} } fi function wg-genkeypair () { local IFDEFAULT=wg1 local IF="${1:-${IFDEFAULT}}" shift case $1 in -h|--help) cat << EOF usage: wg-genkeypair [name] if name is given, a keypair is generated with names "name_key" and "name_pub". If name is not given, the keypair is "${IFDEFAULT}_key" and "${IFDEFAULT}_pub" EOF return ;; esac PRAEFIX="${IF}_" umask 077 wg genkey | tee ${PRAEFIX}key | wg pubkey > ${PRAEFIX}pub cat <<- EOF >&2 Generated keypair: Private (${PRAEFIX}key): $(cat ${PRAEFIX}key) Public (${PRAEFIX}pub): $(cat ${PRAEFIX}pub) EOF cat <<- EOF ${IF} ${PRAEFIX}pub $(cat ${PRAEFIX}pub) EOF } function wg-create-interface () { local IF="wg1" local NET local NETMASK local LISTENPORT local INTERFACEADDR local DNS local POSTUP local PREDOWN local POSTDOWN local PSK local TABLE local GENERATE=false local MTU local PRAEFIX set -- $(getopt -u -o ha:d:gp:i:n:m:a: --long help,if-address:,listenport:,dns:,mtu:,table:,postup:,predown:,postdown:,generate-key,preshared-key: -- "$@" ) echo "@: $@" while [ $# -gt 0 ] do case $1 in -h|--help) shift cat <<- endofhelp usage: wg-create-interface [OPTIONS] OPTIONS: -h|--help -a|--if-address -p|--listenport -d|--dns (multiple times) -n|--network -m|--netmask /24, /32... --mtu default: 1500 -t|--table default: auto --generate-key if set, generate key new. overwrite existing. default: false --postup --predown --postdown --preshared-key endofhelp return ;; -d|--dns) shift DNS=$1 shift ;; -p|--listenport) shift LISTENPORT=$1 shift ;; -a|if-address) shift INTERFACEADDR=$1 shift ;; -n|network) shift NET=$1 shift ;; -m|--netmask) shift NETMASK=$1 shift ;; --mtu) shift MTU=$1 shift ;; -t|--table) shift TABLE=$1 shift ;; --postup) shift POSTUP="${1}" shift ;; --predown) shift PREDOWN="${1}" shift ;; --postdown) shift POSTDOWN="${1}" shift ;; --generate-key) shift GENERATE=true ;; --preshared-key) shift PSK="${1}" ;; --) shift break ;; *) ;; esac done [ $# -eq 0 ] && { echo "Too few arguments. Use »-h« or »--help« for instructions"; return; } # Set interface name to default if not given on commandline local IF="${1:-${IF}}" shift # create file-prefix for key and pubkey from interface-name PRAEFIX="${IF}_" echo PRAEFIX: ${PRAEFIX} # Generate keypair when files do not exist or when they exist and generating is forced (--generate-key) if [ -e "${PRAEFIX}key" ] then ${GENERATE:-false} && wg-genkeypair ${IF} else wg-genkeypair ${IF} fi umask 077 cat <<- EOF >> ${IF}.conf [Interface] Address = ${INTERFACEADDR} ListenPort = ${LISTENPORT:-51280} PrivateKey = $(cat ${PRAEFIX}key) ${MTU:+MTU = ${MTU}} ${TABLE:+Table = ${TABLE}} ${POSTUP:+PostUp = ${POSTUP}} ${PREDOWN:+PostUp = ${PREDOWN}} ${POSTDOWN:+PostUp = ${POSTDOWN}} EOF } #EOF