From 8b03bc4da15b75c0059f5e58c611314ea7dad5b4 Mon Sep 17 00:00:00 2001 From: Luka Vandervelden Date: Wed, 29 May 2019 15:30:23 +0200 Subject: [PATCH 1/4] WIP Passwd#mod_user --- src/passwd.cr | 19 +++++++++++++++++++ src/user.cr | 2 ++ 2 files changed, 21 insertions(+) diff --git a/src/passwd.cr b/src/passwd.cr index 40ef618..11bd3fb 100644 --- a/src/passwd.cr +++ b/src/passwd.cr @@ -171,6 +171,25 @@ class Passwd File.write(@group, group.to_csv + "\n", mode: "a") end + + # FIXME: Edit other important fields. + def mod_user(uid, password_hash : String? = nil) + new_passwd = passwd_as_array.map do |line| + user = AuthD::User.new line + + if uid == user.uid + password_hash.try do |hash| + user.password_hash = hash + end + + user.to_csv + else + line.join(':') + "\n" + end + end + + puts new_passwd.join + end end class AuthD::Group diff --git a/src/user.cr b/src/user.cr index a112322..49b27bb 100644 --- a/src/user.cr +++ b/src/user.cr @@ -1,4 +1,6 @@ +require "json" + class AuthD::User getter login : String getter password_hash : String From a83c3c8e5c4d0cd517b05c7dfdc9cfc26b7c1029 Mon Sep 17 00:00:00 2001 From: Luka Vandervelden Date: Wed, 29 May 2019 15:35:14 +0200 Subject: [PATCH 2/4] WIP Passwd#mod_user --- src/passwd.cr | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/passwd.cr b/src/passwd.cr index 11bd3fb..3e76273 100644 --- a/src/passwd.cr +++ b/src/passwd.cr @@ -188,7 +188,7 @@ class Passwd end end - puts new_passwd.join + File.write @passwd, new_passwd.join end end From 6a19ff604a48463e88b21f63e95e1a4f862b81dc Mon Sep 17 00:00:00 2001 From: Luka Vandervelden Date: Wed, 29 May 2019 16:06:11 +0200 Subject: [PATCH 3/4] ModUser request. --- src/authd.cr | 28 ++++++++++++++++++++++++++++ src/main.cr | 15 +++++++++++++++ src/passwd.cr | 14 ++++++++------ 3 files changed, 51 insertions(+), 6 deletions(-) diff --git a/src/authd.cr b/src/authd.cr index eb33980..2034e3e 100644 --- a/src/authd.cr +++ b/src/authd.cr @@ -12,6 +12,7 @@ module AuthD AddUser GetUser GetUserByCredentials + ModUser # Edit user attributes. end enum ResponseTypes @@ -54,6 +55,13 @@ module AuthD }) end + class ModUserRequest + JSON.mapping({ + uid: Int32, + password: String? + }) + end + class Client < IPC::Client property key : String @@ -134,6 +142,26 @@ module AuthD Exception.new response.payload end end + + def mod_user(uid : Int32, password : String?) : Bool | Exception + payload = Hash(String, String|Int32).new + payload["uid"] = uid + + password.try do |password| + payload["password"] = password + end + + send RequestTypes::ModUser, payload.to_json + + response = read + + case ResponseTypes.new response.type.to_i + when ResponseTypes::Ok + true + else + Exception.new response.payload + end + end end end diff --git a/src/main.cr b/src/main.cr index ccbf703..2c14dcd 100644 --- a/src/main.cr +++ b/src/main.cr @@ -121,6 +121,21 @@ IPC::Service.new "auth" do |event| else client.send ResponseTypes::UserNotFound, "" end + when RequestTypes::ModUser + begin + request = ModUserRequest.from_json payload + rescue e + client.send ResponseTypes::MalformedRequest, e.message || "" + next + end + + password_hash = request.password.try do |s| + Passwd.hash_password s + end + + passwd.mod_user request.uid, password_hash: password_hash + + client.send ResponseTypes::Ok, "" end end end diff --git a/src/passwd.cr b/src/passwd.cr index 3e76273..79cb4d6 100644 --- a/src/passwd.cr +++ b/src/passwd.cr @@ -69,9 +69,7 @@ class Passwd ## # Will fail if the user is found but the password is invalid. def get_user(login : String, password : String) : AuthD::User? - digest = OpenSSL::Digest.new("sha256") - digest << password - hash = digest.hexdigest + hash = Passwd.hash_password password each_user do |user| if user.login == login @@ -138,6 +136,12 @@ class Passwd gid end + def self.hash_password(password) + digest = OpenSSL::Digest.new("sha256") + digest << password + digest.hexdigest + end + def add_user(login, password = nil, uid = nil, gid = nil, home = "/", shell = "/bin/nologin") # FIXME: If user already exists, exception? Replacement? @@ -146,9 +150,7 @@ class Passwd gid = get_free_gid if gid.nil? password_hash = if password - digest = OpenSSL::Digest.new("sha256") - digest << password - digest.hexdigest + Passwd.hash_password password else "x" end From c642851165898b26b5978d522b5b24d2d213557c Mon Sep 17 00:00:00 2001 From: Luka Vandervelden Date: Wed, 29 May 2019 19:45:03 +0200 Subject: [PATCH 4/4] Avatar update through ModUserRequest. --- src/authd.cr | 9 +++++++-- src/main.cr | 4 +++- src/passwd.cr | 21 +++++++++++++++++---- src/user.cr | 7 ++++--- 4 files changed, 31 insertions(+), 10 deletions(-) diff --git a/src/authd.cr b/src/authd.cr index 2034e3e..e97839b 100644 --- a/src/authd.cr +++ b/src/authd.cr @@ -58,7 +58,8 @@ module AuthD class ModUserRequest JSON.mapping({ uid: Int32, - password: String? + password: String?, + avatar: String? }) end @@ -143,7 +144,7 @@ module AuthD end end - def mod_user(uid : Int32, password : String?) : Bool | Exception + def mod_user(uid : Int32, password : String? = nil, avatar : String? = nil) : Bool | Exception payload = Hash(String, String|Int32).new payload["uid"] = uid @@ -151,6 +152,10 @@ module AuthD payload["password"] = password end + avatar.try do |avatar| + payload["avatar"] = avatar + end + send RequestTypes::ModUser, payload.to_json response = read diff --git a/src/main.cr b/src/main.cr index 2c14dcd..2bcceac 100644 --- a/src/main.cr +++ b/src/main.cr @@ -133,7 +133,9 @@ IPC::Service.new "auth" do |event| Passwd.hash_password s end - passwd.mod_user request.uid, password_hash: password_hash + avatar = request.avatar + + passwd.mod_user request.uid, password_hash: password_hash, avatar: avatar client.send ResponseTypes::Ok, "" end diff --git a/src/passwd.cr b/src/passwd.cr index 79cb4d6..6d2a9b2 100644 --- a/src/passwd.cr +++ b/src/passwd.cr @@ -1,5 +1,6 @@ require "csv" require "uuid" +require "base64" require "./user.cr" require "./group.cr" @@ -175,7 +176,7 @@ class Passwd end # FIXME: Edit other important fields. - def mod_user(uid, password_hash : String? = nil) + def mod_user(uid, password_hash : String? = nil, avatar : String? = nil) new_passwd = passwd_as_array.map do |line| user = AuthD::User.new line @@ -184,6 +185,10 @@ class Passwd user.password_hash = hash end + avatar.try do |avatar| + user.avatar = avatar + end + user.to_csv else line.join(':') + "\n" @@ -222,7 +227,15 @@ class AuthD::User @office_phone_number = gecos[2]? @home_phone_number = gecos[3]? @other_contact = gecos[4]? - @avatar = gecos[5]? # CAUTION: NON-STANDARD EXTENSION + + # CAUTION: NON-STANDARD EXTENSION + @avatar = gecos[5]?.try do |x| + if x != "" + Base64.decode_string x + else + nil + end + end end # FIXME: What about those two fields? Keep them, remove them? @@ -235,7 +248,7 @@ class AuthD::User end def gecos - unless @location || @office_phone_number || @home_phone_number || @other_contact + unless @location || @office_phone_number || @home_phone_number || @other_contact || @avatar if @full_name return @full_name else @@ -243,7 +256,7 @@ class AuthD::User end end - [@full_name || "", @location || "", @office_phone_number || "", @home_phone_number || "", @other_contact || ""].join "," + [@full_name || "", @location || "", @office_phone_number || "", @home_phone_number || "", @other_contact || "", Base64.strict_encode(@avatar || "")].join "," end end diff --git a/src/user.cr b/src/user.cr index 49b27bb..9f70a13 100644 --- a/src/user.cr +++ b/src/user.cr @@ -2,10 +2,10 @@ require "json" class AuthD::User - getter login : String - getter password_hash : String getter uid : Int32 getter gid : Int32 + getter login : String + getter password_hash : String getter home : String = "/" getter shell : String = "/bin/nologin" getter groups = Array(String).new @@ -27,7 +27,8 @@ class AuthD::User full_name: String?, office_phone_number: String?, home_phone_number: String?, - other_contact: String? + other_contact: String?, + avatar: String? }) def initialize(@login, @password_hash, @uid, @gid, @home, @shell)