172 lines
3.5 KiB
Ruby
172 lines
3.5 KiB
Ruby
require 'fileutils'
|
|
|
|
POSIX_NAME_PREFIX = "emacs"
|
|
|
|
$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(user)
|
|
$users << user
|
|
$id_map[user.id] = user
|
|
end
|
|
|
|
def create_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}"
|
|
$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(user)
|
|
system("userdel -r #{user.posixname}")
|
|
$users.remove(user)
|
|
$id_map[id] = nil
|
|
end
|
|
|
|
def user_by_posix_name(posix_name)
|
|
user = User.new
|
|
user.id = posix_name[POSIX_NAME_PREFIX.length..-1]
|
|
user.path = "/home/#{posix_name}"
|
|
user.posixname = posix_name
|
|
user
|
|
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
|
|
|
|
################
|
|
|
|
|
|
###########
|
|
# User DB #
|
|
###########
|
|
|
|
def reload_users_from_passwd
|
|
$users = []
|
|
`cut -d: -f1 /etc/passwd`.split("\n").
|
|
select{|u| u.start_with? POSIX_NAME_PREFIX}.
|
|
map{|u| user_by_posix_name(u)}.
|
|
each{|u| add_user(u)}
|
|
end
|
|
|
|
|
|
################################################
|
|
|
|
reload_users_from_passwd
|
|
|
|
|
|
#remove_user 5
|
|
#create_user 3
|
|
#add_ssh_pubkey(get_user(3), "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC7ZKN2fKcUQUaQqDjNCQQBSdqBVGX7lprNCJmceDBfybhbnuZJ8KvzJJIJIIbzqheW5BVCfkWJY6OgkpAumLWSRCS5n2+AnDHwQgpKDS93OeV+9/kattVtsVUBZaghymyJ2UfA0r918dkxcT9SZbNSl9raiDUUmj3JY8UM219BQP7BRqoZ6e/YZz9lO7ORy6yQT6fIMaVOaZcoDPr6oyNJfadm9POvS/Wl63onoRI9dzpHQG9RuHCcUhHJhkGtzY7GeRWc85WqA9Q4vYo0SK5Je9BG1cvAAVTfV+eYEJEiSDMwWj60roH0C3/ipmzxD/kWqg6YBJWL+XAyQkDnmbuD christoffermadsen@strawberry.thedevcave.net")
|