A collection of scripts & documentation for HorrificDev hosting.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 

97 lines
2.6 KiB

  1. module daemon;
  2. import config.global : GlobalConfig;
  3. import ddbus;
  4. import std.stdio;
  5. import model.user : User;
  6. import model.status : Status;
  7. import jsonizer.tojson;
  8. import jsonizer.fromjson;
  9. import jsonizer.common;
  10. import std.conv;
  11. import core.sys.posix.unistd : getlogin;
  12. import service.index : DaemonCommand, daemon_cmds;
  13. import service.users : encryptUserMessage, decryptUserMessage;
  14. class Daemon {
  15. GlobalConfig conf;
  16. Connection conn;
  17. this(GlobalConfig conf) {
  18. this.conf = conf;
  19. this.conn = connectToBus();
  20. }
  21. /**
  22. * Daemon service; executed as root.
  23. */
  24. void start() {
  25. // route each message to daemon_cmds array
  26. MessageRouter router = new MessageRouter();
  27. foreach (name, cmd; daemon_cmds) {
  28. MessagePattern pattern = MessagePattern("/root", "dev.horrific.daemon", name);
  29. router.setHandler!(string, string, string)(pattern, (string userJson, string encryptedData) {
  30. Status result;
  31. result.code = 0;
  32. try {
  33. // get user from database
  34. User providedUser = fromJSONString!User(userJson);
  35. User* dbUserRef = providedUser.id in this.conf.users.contents;
  36. if (dbUserRef is null)
  37. throw new Exception("Authentication error: user " ~ providedUser.id ~ " does not exist.");
  38. // decrypt passed data
  39. // - This is less for keeping the content "secure" and more to prevent user spoofing;
  40. // users cannot access each others' private *or* public keys; even with the public
  41. // key, it would take some effort to create a coherent message that can be decrypted
  42. // by it.
  43. User dbUser = *dbUserRef;
  44. string data = decryptUserMessage(dbUser, encryptedData);
  45. // attempt function call
  46. result.message = (*cmd)(this.conf, dbUser, data);
  47. } catch (Exception e) {
  48. result.code = 1;
  49. result.message = e.msg;
  50. }
  51. // encode result/status
  52. return result.toJSONString();
  53. });
  54. }
  55. registerRouter(this.conn, router);
  56. writeln("Getting name...");
  57. bool gotem = requestName(this.conn, "dev.horrific.daemon");
  58. writeln("Got name: ", gotem);
  59. simpleMainLoop(this.conn);
  60. }
  61. PathIface proxy = null;
  62. string call(string name, string data) {
  63. if (this.proxy is null)
  64. this.proxy = new PathIface(conn, "dev.horrific.daemon", "/root", "dev.horrific.daemon");
  65. // call dbus method
  66. User user;
  67. user.name = to!string(getlogin());
  68. string encryptedData = encryptUserMessage(user, data);
  69. string resultJson = this.proxy.call!string(name, user.toJSONString(), encryptedData);
  70. // parse JSON status/result
  71. Status result = fromJSONString!Status(resultJson);
  72. if (result.code != 0)
  73. throw new Exception(result.message);
  74. else return result.message;
  75. }
  76. }