aboutsummaryrefslogtreecommitdiff
path: root/ssh/fsi-copy-id
blob: db5b35cd4de5aad16c15c70c874e38806b1129d7 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
#!/usr/bin/env expect

# Author: Michael Weiss
# License: Unlicense (https://unlicense.org/UNLICENSE)
# Note: Using Python would've probably been a better idea...

proc printHelp {} {
  send_user "Usage:\n"
  send_user "\tfsi-copy-id FILE\n"
  send_user "\t\tWhere FILE is your SSH public key file.\n"
  send_user "\tfsi-copy-id -h\n"
  send_user "\tfsi-copy-id --help\n"
  send_user "\t\tPrint this help.\n"
  exit 0
}

proc parseArguments {} {
  global argc
  if { $argc != 1 } {
    send_error "Error: Wrong usage.\n"
    send_error "Try 'fsi-copy-id --help' for more information.\n"
    exit 1
  }
  global argv
  if { [lindex $argv 0] == "-h" || [lindex $argv 0] == "--help" } {
    printHelp
  }
  set fileName [lindex $argv 0]
  if { [file isfile $fileName] == 0 } {
    send_error "Error: The file $fileName doesn't exist.\n"
    exit 1
  }
  return $fileName
}

proc getSshUser {} {
  send_user "Please enter your SSH username: "
  expect_user -re "(.*)\n"
  set user $expect_out(1,string)
  return $user
}

proc getSshPassword {} {
  stty -echo
  send_user "Please enter your SSH password: "
  expect_user -re "(.*)\n"
  set password $expect_out(1,string)
  send_user "\n"
  stty echo
  return $password
}

# Parse the arguments and try to get the identity file
set identityFile [parseArguments]

# Request the SSH user
set user [getSshUser]
# Request the SSH password
set password [getSshPassword]

set hosts {"amy" "anja" "kim" "lara" "nina" "sessel" "sofa" "teri" "trinity"}
# Optional: luna

# Try to install the key
set hostsSkipped 0
set keysInstalled 0
foreach host $hosts {
  # "-n" for a dry-run
  spawn "ssh-copy-id" "-i" "$identityFile" "-o" "StrictHostKeyChecking=yes" "$user@$host.fsi.uni-tuebingen.de"
  expect {
    "$user@$host.fsi.uni-tuebingen.de's password:" {send "$password\r"}
    "ERROR: Host key verification failed." {
      send_error "Please make sure that you follow our setup: "
      send_error "https://wiki.fsi.uni-tuebingen.de/interna/admin-doku/ssh\n"
      send_error "You must either use the UserKnownHostsFile option "
      send_error "or have all host keys in your ~/.ssh/known_hosts\n"
      exit 1
    }
    "WARNING: All keys were skipped because they already exist on the remote system." {
      incr hostsSkipped; continue
    }
    timeout {
      puts stderr "Error: Timeout."
      exit 1
    }
    eof {
      puts stderr "Error: Something unexpected happened."
      exit 1
    }
  }
  expect {
    "Number of key(s) added:" {incr keysInstalled}
    "Permission denied, please try again." {
      puts stderr "Error: Wrong password."
      exit 1
    }
    timeout {
      puts stderr "Error: Timeout."
      exit 1
    }
    eof {
      puts stderr "Error: Something unexpected happened."
      exit 1
    }
  }
}

# No error detected -> success
send_user "Success:\n"
send_user "  Total hosts: [llength $hosts]\n"
send_user "  Installed key on $keysInstalled hosts.\n"
send_user "  Key already installed on $hostsSkipped hosts.\n"