be 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558
  1. #! /usr/bin/env bash
  2. # change credentials - symlink different credential files
  3. #
  4. # Usage: be [options] who
  5. # arguments
  6. # who name of identity
  7. #
  8. # options
  9. #
  10. # Select credentials
  11. #
  12. # -a|--aws change/list aws credentials ONLY
  13. # -g|--gnupg change/list gnupgcredentials ONLY
  14. # -p|--pass change/list pas credentials ONLY
  15. # -s|--ssh change/list ssh credentials ONLY
  16. # -t|--git change/list git credentials ONLY
  17. #
  18. # Select operation
  19. #
  20. # -l|--list list availabe credentials.
  21. # -w|--whoami list current identities
  22. #
  23. # Other
  24. #
  25. # -d|--debug debug output
  26. # -h|--help print usage
  27. # -v|--verbose verbose output
  28. #
  29. # e.g.
  30. #
  31. # If ~/.gnupg.$1 exists, link to ~/.gnupg
  32. # If ~/.ssh/id_{dsa,rsa}.$1 exists, link to ~/.ssh/id_{dsa,rsa} and add to ssh agent
  33. # If ~/.aws/credentials.$1 exists, link to ~/.aws/credentials
  34. #
  35. # FILES
  36. # * SSH Files
  37. #
  38. # ~/.ssh/id_{dsa,rsa}.IDENTITY - SSH identify file for IDENTITY
  39. # ~/.ssh/id_{dsa,rsa} - Symlink to SSH identity
  40. #
  41. # ~/.ssh/authorized_keys.IDENTITY - SSH authorized keys for IDENTITY
  42. # ~/.ssh/authorized_keys - Symlink to SSH authorized_keys file
  43. #
  44. # ~/.ssh/config.IDENTITY - SSH config for IDENTITY
  45. # ~/.ssh/config - Symlink to SSH config file
  46. #
  47. # ~/,gitconfig.IDENTITY - git config file
  48. #
  49. # * GPG Files
  50. #
  51. # * AWS files
  52. #
  53. # * pass(1) files
  54. #
  55. # * org files
  56. #
  57. # TO DO ITEMS
  58. #
  59. # * TODO finish documenting FILES
  60. # * TODO deal with .pem files
  61. # * TODO maybe make this not bash (python? go?)
  62. # * TODO make a general configruation format for different identites
  63. # - e.g. so that there would only be one "list" or "whoami" function
  64. # for all identities
  65. # * TODO add documentation
  66. #
  67. # * TODO deal with git identities
  68. # + Use XDG-CONFIG-HOME to switch identities?
  69. # http://git.661346.n2.nabble.com/What-is-XDG-CONFIG-HOME-for-exactly-td7627117.html
  70. # + See https://gist.github.com/jexchan/2351996
  71. set -e; set -u # this is bash. Be safe out there.
  72. unalias cd 2>/dev/null || true
  73. # Helper functions
  74. PROG=`basename "$0" | tr -d '\n'`
  75. function info() { echo ${PROG}\: info: "$@" 1>&2; }
  76. function warn() { echo ${PROG}\: warning: "$@" 1>&2; }
  77. function error() { echo ${PROG}\: error: "$@" 1>&2; }
  78. function debug() { [[ -v DEBUG ]] && echo ${PROG}\: debug: "$@" 1>&2 || true ; }
  79. function die() { echo ${PROG}\: fatal: "$@" 1>&2 && exit 1; }
  80. function usage() {
  81. debug "in ${FUNCNAME[0]}"
  82. if [[ "$#" -gt 0 ]]; then
  83. warn $@
  84. fi
  85. cat <<END 1>&2
  86. Usage: be [options] who
  87. arguments
  88. who name of identity
  89. options
  90. Select credentials
  91. -a|--aws change/list aws credentials ONLY
  92. -g|--gnupg change/list gnupgcredentials ONLY
  93. -p|--pass change/list pas credentials ONLY
  94. -s|--ssh change/list ssh credentials ONLY
  95. -t|--git change/list git credentials ONLY
  96. Select operation
  97. -l|--list list availabe credentials.
  98. -w|--whoami list current identities
  99. Other
  100. -d|--debug debug output
  101. -h|--help print usage
  102. -v|--verbose verbose output
  103. END
  104. exit 1
  105. }
  106. # See
  107. #
  108. # https://wiki.archlinux.org/index.php/GnuPG#gpg-agent
  109. #
  110. # I'm pretty sure mere mortals can't grok gpg in fullness.
  111. function gpg_list() {
  112. # list available gpg credentail sets (diretories)
  113. info available GPG credentials sets
  114. ls -ld ~/.gnupg.* || true
  115. echo
  116. }
  117. function gpg_whoami() {
  118. # list current gpg identity
  119. if [ ! -L ~/.gnupg ]; then warn "No ~/.gnupg directory"; echo; return; fi
  120. info Current gpg credential set
  121. info
  122. ls -ld ~/.gnupg || true
  123. echo "GET_PASSPHRASE --no-ask NotCachedID Err Pmt Des" | gpg-connect-agent
  124. echo
  125. }
  126. function gpg_become() {
  127. # change gpg identity
  128. rm -f ~/.gnupg || true
  129. ln -s ~/.gnupg."${who}" ~/.gnupg
  130. }
  131. function aws_list() {
  132. # list available aws credentials
  133. if ! cd ~/.aws; then warn "No ~/.aws credentials"; echo; return; fi
  134. info available AWS credentials and configs
  135. ls -ld credentials.* config.* || true
  136. echo
  137. }
  138. function aws_whoami() {
  139. # list current aws identity
  140. echo foo
  141. if ! cd ~/.aws; then warn "No ~/.aws credentials"; echo; return; fi
  142. info Current aws credentials
  143. info
  144. ls -ld credentials config || true
  145. echo
  146. }
  147. function aws_become() {
  148. # change aws identity
  149. if ! cd ~/.aws; then warn "No ~/.aws credentials"; echo; return; fi
  150. aws_creds="credentials.""${who}"
  151. if [ ! -f "${aws_creds}" ]; then
  152. warn file "${aws_creds}" does not exist. Not changing aws identity.
  153. else
  154. [[ -v VERBOSE ]] && set -x
  155. rm -f credentials || true
  156. ln -s "${aws_creds}" credentials
  157. [[ -v VERBOSE ]] && set +x
  158. fi
  159. aws_config="config.""${who}"
  160. if [ ! -f "${aws_config}" ]; then
  161. warn file "${aws_config}" does not exist. Not installing.
  162. else
  163. [[ -v VERBOSE ]] && set -x
  164. rm -f config || true
  165. ln -s "${aws_config}" config
  166. [[ -v VERBOSE ]] && set +x
  167. fi
  168. }
  169. function ssh_list() {
  170. # list available ssh credentials
  171. if ! cd ~/.ssh; then warn "No ~/.ssh credentials"; echo; return; fi
  172. info available SSH credentials
  173. ls -ld id_rsa.* id_dsa.* authorized_keys.* config.* || true
  174. echo
  175. }
  176. function ssh_whoami() {
  177. # list current ssh identity
  178. if ! cd ~/.ssh; then warn "No ~/.ssh credentials"; echo; return; fi
  179. info Current SSH identities
  180. info
  181. ls -ld id_??? || warn "no ~/.ssh/id_{rsa,dsa} file"
  182. ls -ld authorized_keys || warn "no authorized_keys file"
  183. ls -ld config || warn "no config file"
  184. info SSH Agent Identities
  185. ssh-add -l
  186. echo
  187. }
  188. function ssh_become() {
  189. # change ssh identity
  190. if ! cd ~/.ssh; then warn "No ~/.ssh credentials"; echo; return; fi
  191. rsa_creds="id_rsa.""${who}"
  192. dsa_creds="id_dsa.""${who}"
  193. authorized_keys="authorized_keys.""${who}"
  194. config="config.""${who}"
  195. if [ -f "${dsa_creds}" ]; then
  196. ssh_creds="${dsa_creds}"
  197. elif [ -f "${rsa_creds}" ]; then
  198. ssh_creds="${rsa_creds}"
  199. else
  200. echo "No ssh creds found. "${rsa_creds}" and "${dsa_creds}" do not exist."
  201. exit 1
  202. fi
  203. # symlnk ssh creds into ~/.ssh
  204. target=`basename $ssh_creds ".""${who}"`
  205. if [ -f "${ssh_creds}" ]; then
  206. [[ -v VERBOSE ]] && set +x
  207. rm -f "${target}" || true
  208. ln -s "${ssh_creds}" "${target}"
  209. chmod 400 "${target}"
  210. ssh-add "${ssh_creds}"
  211. [[ -v VERBOSE ]] && set -x
  212. fi
  213. # symlnk authinfo creds into ~/.ssh
  214. target=`basename $authorized_keys ".""${who}"`
  215. if [ -f "${authorized_keys}" ]; then
  216. [[ -v VERBOSE ]] && set +x
  217. rm -f "${target}" || true
  218. ln -s "${authorized_keys}" "${target}"
  219. chmod 644 "${target}"
  220. [[ -v VERBOSE ]] && set -x
  221. fi
  222. # symlnk config into ~/.ssh
  223. target=`basename $config ".""${who}"`
  224. if [ -f "${config}" ]; then
  225. [[ -v VERBOSE ]] && set +x
  226. rm -f "${target}" || true
  227. ln -s "${config}" "${target}"
  228. chmod 644 "${target}"
  229. [[ -v VERBOSE ]] && set -x
  230. fi
  231. }
  232. function pass_list() {
  233. # list available pass credentail sets (diretories)
  234. info available pass credentials sets
  235. ls -ld ~/.password-store.* || true
  236. echo
  237. }
  238. function pass_whoami() {
  239. # list current pass identity
  240. if [ ! -L ~/.password-store ]; then warn "No ~/.password-store directory"; echo; return; fi
  241. info Current pass credential set
  242. info
  243. ls -ld ~/.password-store || true
  244. echo
  245. }
  246. function pass_become() {
  247. # change pass identity
  248. rm -f ~/.password-store || true
  249. ln -s ~/.password-store."${who}" ~/.password-store
  250. gpg_become # need to switch GPG IDs too
  251. }
  252. function org_list() {
  253. # list available org credentail sets (diretories)
  254. info available org credentials sets
  255. ls -ld ~/Org.* || true
  256. echo
  257. }
  258. function org_whoami() {
  259. # list current org identity
  260. if [ ! -L ~/Org ]; then warn "No ~/Org directory"; echo; return; fi
  261. info Current org credential set
  262. info
  263. ls -ld ~/Org || true
  264. echo
  265. }
  266. function org_become() {
  267. # change org identity
  268. rm -f ~/Org || true
  269. ln -s ~/Org."${who}" ~/Org
  270. }
  271. function git_list() {
  272. # list available git credentail sets (diretories)
  273. info available git credentials sets
  274. ls -ld ~/.gitconfig.* || true
  275. echo
  276. }
  277. function git_whoami() {
  278. # list current git identity
  279. if [ ! -L ~/.gitconfig ]; then warn "No git config"; echo; return; fi
  280. info Current git credential set
  281. info
  282. ls -ld ~/.gitconfig || true
  283. echo
  284. }
  285. function git_become() {
  286. # change git identity
  287. rm -f ~/.gitconfig || true
  288. ln -s ~/.gitconfig."${who}" ~/.gitconfig
  289. #gpg_become # need to switch GPG IDs too
  290. }
  291. #
  292. # "main()" begins here
  293. #
  294. # Defaults
  295. SSH=1
  296. AWS=1
  297. GPG=1
  298. PASSWORD=1
  299. ORG=1
  300. GIT=1
  301. # parse global options
  302. for i in "$@"
  303. do
  304. case $i in
  305. -a|--aws)
  306. AWS=1
  307. unset GIT
  308. unset SSH
  309. unset GPG
  310. unset PASSWORD
  311. unset ORG
  312. d_flag="-d"
  313. shift # past argument with no value
  314. ;;
  315. -d|--debug)
  316. DEBUG=1
  317. d_flag="-d"
  318. shift # past argument with no value
  319. ;;
  320. -g|--gnupg)
  321. GPG=1
  322. unset GIT
  323. unset AWS
  324. unset SSH
  325. unset PASSWORD
  326. unset ORG
  327. g_flag="-g"
  328. shift # past argument with no value
  329. ;;
  330. -h|--help)
  331. usage
  332. ;;
  333. -l|--list)
  334. LIST=1
  335. d_flag="-d"
  336. shift # past argument with no value
  337. ;;
  338. -o|--org)
  339. ORG=1
  340. unset GIT
  341. unset PASSWORD
  342. unset AWS
  343. unset SSH
  344. unset GPG
  345. p_flag="-p"
  346. shift # past argument with no value
  347. ;;
  348. -p|--pass)
  349. PASSWORD=1
  350. unset GIT
  351. unset AWS
  352. unset SSH
  353. unset GPG
  354. unset ORG
  355. p_flag="-p"
  356. shift # past argument with no value
  357. ;;
  358. -t|--git)
  359. GIT=1
  360. unset PASSWORD
  361. unset AWS
  362. unset SSH
  363. unset GPG
  364. unset ORG
  365. p_flag="-p"
  366. shift # past argument with no value
  367. ;;
  368. -s|--ssh)
  369. SSH=1
  370. unset GIT
  371. unset AWS
  372. unset GPG
  373. unset PASSWORD
  374. unset ORG
  375. d_flag="-d"
  376. shift # past argument with no value
  377. ;;
  378. -v|--verbose)
  379. VERBOSE=1
  380. v_flag="-v"
  381. shift # past argument with no value
  382. ;;
  383. -w|--whoami)
  384. WHOAMI=1
  385. v_flag="-v"
  386. shift # past argument with no value
  387. ;;
  388. -*|--*)
  389. usage "Unknown state option: $i"
  390. ;;
  391. esac
  392. done
  393. # Pull off command line args
  394. if [[ ! -v LIST && ! -v WHOAMI ]]; then
  395. if [ "$#" -ne 1 ]; then
  396. usage need a username
  397. fi
  398. who="${1}"
  399. fi
  400. if [[ ! -v SSH && ! -v AWS && ! -v ORG && ! -v PASSWORD && ! -v GPG && ! -v GIT ]]; then
  401. die "Must specify at least one of '--aws' '--ssh' '--gnupg' '--pass'"
  402. fi
  403. # list/show/become aws credentials
  404. if [ -v AWS ]; then
  405. if [[ -v LIST ]]; then
  406. aws_list
  407. elif [[ -v WHOAMI ]]; then
  408. aws_whoami
  409. else
  410. aws_become
  411. fi
  412. fi
  413. # list/show/become ssh credentials
  414. if [ -v SSH ]; then
  415. if [[ -v LIST ]]; then
  416. ssh_list
  417. elif [[ -v WHOAMI ]]; then
  418. ssh_whoami
  419. else
  420. ssh_become
  421. fi
  422. fi
  423. # list/show/become GPG credentials
  424. if [ -v GPG ]; then
  425. if [[ -v LIST ]]; then
  426. gpg_list
  427. elif [[ -v WHOAMI ]]; then
  428. gpg_whoami
  429. else
  430. gpg_become
  431. fi
  432. fi
  433. # list/show/become pass credentials
  434. if [ -v PASSWORD ]; then
  435. if [[ -v LIST ]]; then
  436. pass_list
  437. elif [[ -v WHOAMI ]]; then
  438. pass_whoami
  439. else
  440. pass_become
  441. fi
  442. fi
  443. # list/show/become git credentials
  444. if [ -v GIT ]; then
  445. if [[ -v LIST ]]; then
  446. git_list
  447. elif [[ -v WHOAMI ]]; then
  448. git_whoami
  449. else
  450. git_become
  451. fi
  452. fi
  453. # list/show/become org credentials
  454. if [ -v ORG ]; then
  455. if [[ -v LIST ]]; then
  456. org_list
  457. elif [[ -v WHOAMI ]]; then
  458. org_whoami
  459. else
  460. org_become
  461. fi
  462. fi