require 'fileutils' POSIX_NAME_PREFIX = "emacs" $user_count = 0 $users = [] $id_map = {} ##################### # User manipulation # ##################### class User attr_accessor :id, :path, :posixname def to_s "#{@id}, #{@path}" end end def get_user(id) $id_map[id] end def add_user(id) if not system("useradd -m #{POSIX_NAME_PREFIX}#{id}") then raise "User creation failed" end user = User.new user.id = id user.path = "/home/#{POSIX_NAME_PREFIX}#{id}" user.posixname = "#{POSIX_NAME_PREFIX}#{id}" $user_count += 1 $users << user $id_map[id] = user FileUtils.mkdir "#{user.path}/.ssh" FileUtils.touch "#{user.path}/.ssh/authorized_keys" FileUtils.chown_R user.id, user.id, "#{user.path}/.ssh" user end def remove_user(id) system("userdel -r #{POSIX_NAME_PREFIX}#{id}") $user_count -= 1 end #################### # Key manipulation # #################### class SSHKey attr_accessor :cipher, :pubkey, :comment def initialize(cipher,pubkey,comment="") @cipher = cipher @pubkey = pubkey @comment = comment end def ==(o) o.class == self.class && o.attrs == attrs end def pretty "#{@cipher} #{@comment}" end def to_s "ssh-#{@cipher} #{@pubkey} #{@comment}" end def attrs [@cipher, @pubkey, @comment] end end def get_ssh_keyfile(user,mode,&block) file = File.open("#{user.path}/.ssh/authorized_keys",mode) return file unless block_given? yield(file) ensure file.close end def get_ssh_pubkeys(user) extract_ssh_pubkeys("#{user.path}/.ssh/authorized_keys") end def add_ssh_pubkey(user,key) if not valid_pubkey? key then raise "Public key not valid" end get_ssh_keyfile(user,"a") do |key_file| key_file << "#{key.to_s}\n" end end def reset_pubkeys(user) FileUtils.rm "#{user.path}/.ssh/authorized_keys" FileUtils.touch "#{user.path}/.ssh/authorized_keys" FileUtils.chown_R user.id, user.id, "#{user.path}/.ssh" end def remove_ssh_pubkey(user,key) keys = get_ssh_pubkeys(user) reset_pubkeys(user) keys.each{ |k| unless k == key then add_ssh_pubkey(user,k) end} end def remove_ssh_pubkey_by_key end def remove_ssh_pubkey_by_comment end def valid_pubkey?(key) IO.popen("ssh-keygen -qlf -","r+") do |io| io.write key.to_s io.close_write io.read end if $?.to_i == 0 true else false end end def extract_ssh_pubkeys(file) File.open(file,"r") do |f| f.read.split("\n").select{ |line| line[0..2] == "ssh" }.map{ |ks| k = ks.split(" "); SSHKey.new(k[0][4..6], k[1], k[2]) } end end ################## remove_user 5 add_user 5 add_ssh_pubkey(get_user(5), "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC7ZKN2fKcUQUaQqDjNCQQBSdqBVGX7lprNCJmceDBfybhbnuZJ8KvzJJIJIIbzqheW5BVCfkWJY6OgkpAumLWSRCS5n2+AnDHwQgpKDS93OeV+9/kattVtsVUBZaghymyJ2UfA0r918dkxcT9SZbNSl9raiDUUmj3JY8UM219BQP7BRqoZ6e/YZz9lO7ORy6yQT6fIMaVOaZcoDPr6oyNJfadm9POvS/Wl63onoRI9dzpHQG9RuHCcUhHJhkGtzY7GeRWc85WqA9Q4vYo0SK5Je9BG1cvAAVTfV+eYEJEiSDMwWj60roH0C3/ipmzxD/kWqg6YBJWL+XAyQkDnmbuD christoffermadsen@strawberry.thedevcave.net")