10232: Own just a section of authorized_keys instead of clobbering the whole thing...
authorTom Clegg <tom@curoverse.com>
Tue, 18 Oct 2016 12:35:13 +0000 (08:35 -0400)
committerTom Clegg <tom@curoverse.com>
Tue, 18 Oct 2016 12:35:13 +0000 (08:35 -0400)
services/login-sync/bin/arvados-login-sync

index b25ed942fb350751d5d476889ca164897feca160..89f6b03f8a4e7d9abc5e438b7b81369462403454 100755 (executable)
@@ -14,6 +14,13 @@ req_envs.each do |k|
   end
 end
 
+exclusive_mode = ARGV.index("--exclusive")
+exclusive_banner = "#######################################################################################
+#  THIS FILE IS MANAGED BY #{$0} -- CHANGES WILL BE OVERWRITTEN  #
+#######################################################################################\n\n"
+start_banner = "### BEGIN Arvados-managed keys -- changes between markers will be overwritten\n"
+end_banner = "### END Arvados-managed keys -- changes between markers will be overwritten\n"
+
 keys = ''
 
 seen = Hash.new
@@ -87,20 +94,34 @@ begin
     @homedir = Etc.getpwnam(l[:username]).dir
     userdotssh = File.join(@homedir, ".ssh")
     Dir.mkdir(userdotssh) if !File.exists?(userdotssh)
-    @key = "#######################################################################################
-#  THIS FILE IS MANAGED BY #{$0} -- CHANGES WILL BE OVERWRITTEN  #
-#######################################################################################\n\n"
-    @key += keys[l[:username]].join("\n") + "\n"
-    userauthkeys = File.join(userdotssh, "authorized_keys")
-    if !File.exists?(userauthkeys) or IO::read(userauthkeys) != @key then
-      f = File.new(userauthkeys, 'w')
-      f.write(@key)
+    newkeys = keys[l[:username]].join("\n") + "\n"
+    keysfile = File.join(userdotssh, "authorized_keys")
+
+    if File.exists?(keysfile)
+      oldkeys = IO::read(keysfile)
+    else
+      oldkeys = ""
+    end
+
+    if exclusive_mode
+      newkeys = exclusive_banner + newkeys
+    elsif oldkeys.start_with?(exclusive_banner)
+      newkeys = start_banner + newkeys + end_banner
+    elsif (m = /^(.*?\n|)#{start_banner}(.*?\n|)#{end_banner}(.*)/m.match(oldkeys))
+      newkeys = m[1] + start_banner + newkeys + end_banner + m[3]
+    else
+      newkeys = start_banner + newkeys + end_banner + oldkeys
+    end
+
+    if oldkeys != newkeys then
+      f = File.new(keysfile, 'w')
+      f.write(newkeys)
       f.close()
     end
     FileUtils.chown_R(l[:username], nil, userdotssh)
     File.chmod(0700, userdotssh)
     File.chmod(0750, @homedir)
-    File.chmod(0600, userauthkeys)
+    File.chmod(0600, keysfile)
   end
 
   devnull.close