gardesk/gardm / 41a679f

Browse files

power actions via logind and deployment scripts

Add systemd-logind integration for power actions (shutdown, reboot,
suspend) via D-Bus. Update system configuration for Fedora compatibility.

Changes:
- Add zbus dependency for D-Bus communication
- Add power.rs module with logind integration
- Update PAM config based on SDDM's Fedora configuration
- Update systemd service for better compatibility
- Add deployment scripts:
- install.sh: installs binaries, configs, and service
- test-gardm.sh: safe testing on separate VT/display
- swap-dm.sh: safely swap from SDDM to gardm with rollback
Authored by mfwolffe <wolffemf@dukes.jmu.edu>
SHA
41a679f2d9f786d94b46f2a3b929fbba99d251d2
Parents
839cdcb
Tree
ed836da

10 changed files

StatusFile+-
M Cargo.lock 673 10
M etc/gardm.service 7 10
M etc/pam.d/gardm 22 6
M gardmd/Cargo.toml 1 0
M gardmd/src/lib.rs 1 0
M gardmd/src/main.rs 27 19
A gardmd/src/power.rs 91 0
A scripts/install.sh 87 0
A scripts/swap-dm.sh 173 0
A scripts/test-gardm.sh 87 0
Cargo.lockmodified
@@ -79,6 +79,154 @@ version = "1.0.1"
79
 source = "registry+https://github.com/rust-lang/crates.io-index"
79
 source = "registry+https://github.com/rust-lang/crates.io-index"
80
 checksum = "175571dd1d178ced59193a6fc02dde1b972eb0bc56c892cde9beeceac5bf0f6b"
80
 checksum = "175571dd1d178ced59193a6fc02dde1b972eb0bc56c892cde9beeceac5bf0f6b"
81
 
81
 
82
+[[package]]
83
+name = "async-broadcast"
84
+version = "0.7.2"
85
+source = "registry+https://github.com/rust-lang/crates.io-index"
86
+checksum = "435a87a52755b8f27fcf321ac4f04b2802e337c8c4872923137471ec39c37532"
87
+dependencies = [
88
+ "event-listener",
89
+ "event-listener-strategy",
90
+ "futures-core",
91
+ "pin-project-lite",
92
+]
93
+
94
+[[package]]
95
+name = "async-channel"
96
+version = "2.5.0"
97
+source = "registry+https://github.com/rust-lang/crates.io-index"
98
+checksum = "924ed96dd52d1b75e9c1a3e6275715fd320f5f9439fb5a4a11fa51f4221158d2"
99
+dependencies = [
100
+ "concurrent-queue",
101
+ "event-listener-strategy",
102
+ "futures-core",
103
+ "pin-project-lite",
104
+]
105
+
106
+[[package]]
107
+name = "async-executor"
108
+version = "1.13.3"
109
+source = "registry+https://github.com/rust-lang/crates.io-index"
110
+checksum = "497c00e0fd83a72a79a39fcbd8e3e2f055d6f6c7e025f3b3d91f4f8e76527fb8"
111
+dependencies = [
112
+ "async-task",
113
+ "concurrent-queue",
114
+ "fastrand",
115
+ "futures-lite",
116
+ "pin-project-lite",
117
+ "slab",
118
+]
119
+
120
+[[package]]
121
+name = "async-fs"
122
+version = "2.2.0"
123
+source = "registry+https://github.com/rust-lang/crates.io-index"
124
+checksum = "8034a681df4aed8b8edbd7fbe472401ecf009251c8b40556b304567052e294c5"
125
+dependencies = [
126
+ "async-lock",
127
+ "blocking",
128
+ "futures-lite",
129
+]
130
+
131
+[[package]]
132
+name = "async-io"
133
+version = "2.6.0"
134
+source = "registry+https://github.com/rust-lang/crates.io-index"
135
+checksum = "456b8a8feb6f42d237746d4b3e9a178494627745c3c56c6ea55d92ba50d026fc"
136
+dependencies = [
137
+ "autocfg",
138
+ "cfg-if",
139
+ "concurrent-queue",
140
+ "futures-io",
141
+ "futures-lite",
142
+ "parking",
143
+ "polling",
144
+ "rustix",
145
+ "slab",
146
+ "windows-sys 0.61.2",
147
+]
148
+
149
+[[package]]
150
+name = "async-lock"
151
+version = "3.4.2"
152
+source = "registry+https://github.com/rust-lang/crates.io-index"
153
+checksum = "290f7f2596bd5b78a9fec8088ccd89180d7f9f55b94b0576823bbbdc72ee8311"
154
+dependencies = [
155
+ "event-listener",
156
+ "event-listener-strategy",
157
+ "pin-project-lite",
158
+]
159
+
160
+[[package]]
161
+name = "async-process"
162
+version = "2.5.0"
163
+source = "registry+https://github.com/rust-lang/crates.io-index"
164
+checksum = "fc50921ec0055cdd8a16de48773bfeec5c972598674347252c0399676be7da75"
165
+dependencies = [
166
+ "async-channel",
167
+ "async-io",
168
+ "async-lock",
169
+ "async-signal",
170
+ "async-task",
171
+ "blocking",
172
+ "cfg-if",
173
+ "event-listener",
174
+ "futures-lite",
175
+ "rustix",
176
+]
177
+
178
+[[package]]
179
+name = "async-recursion"
180
+version = "1.1.1"
181
+source = "registry+https://github.com/rust-lang/crates.io-index"
182
+checksum = "3b43422f69d8ff38f95f1b2bb76517c91589a924d1559a0e935d7c8ce0274c11"
183
+dependencies = [
184
+ "proc-macro2",
185
+ "quote",
186
+ "syn 2.0.114",
187
+]
188
+
189
+[[package]]
190
+name = "async-signal"
191
+version = "0.2.13"
192
+source = "registry+https://github.com/rust-lang/crates.io-index"
193
+checksum = "43c070bbf59cd3570b6b2dd54cd772527c7c3620fce8be898406dd3ed6adc64c"
194
+dependencies = [
195
+ "async-io",
196
+ "async-lock",
197
+ "atomic-waker",
198
+ "cfg-if",
199
+ "futures-core",
200
+ "futures-io",
201
+ "rustix",
202
+ "signal-hook-registry",
203
+ "slab",
204
+ "windows-sys 0.61.2",
205
+]
206
+
207
+[[package]]
208
+name = "async-task"
209
+version = "4.7.1"
210
+source = "registry+https://github.com/rust-lang/crates.io-index"
211
+checksum = "8b75356056920673b02621b35afd0f7dda9306d03c79a30f5c56c44cf256e3de"
212
+
213
+[[package]]
214
+name = "async-trait"
215
+version = "0.1.89"
216
+source = "registry+https://github.com/rust-lang/crates.io-index"
217
+checksum = "9035ad2d096bed7955a320ee7e2230574d28fd3c3a0f186cbea1ff3c7eed5dbb"
218
+dependencies = [
219
+ "proc-macro2",
220
+ "quote",
221
+ "syn 2.0.114",
222
+]
223
+
224
+[[package]]
225
+name = "atomic-waker"
226
+version = "1.1.2"
227
+source = "registry+https://github.com/rust-lang/crates.io-index"
228
+checksum = "1505bd5d3d116872e7271a6d4e16d81d0c8570876c8de68093a09ac269d8aac0"
229
+
82
 [[package]]
230
 [[package]]
83
 name = "autocfg"
231
 name = "autocfg"
84
 version = "1.5.0"
232
 version = "1.5.0"
@@ -123,6 +271,28 @@ version = "2.10.0"
123
 source = "registry+https://github.com/rust-lang/crates.io-index"
271
 source = "registry+https://github.com/rust-lang/crates.io-index"
124
 checksum = "812e12b5285cc515a9c72a5c1d3b6d46a19dac5acfef5265968c166106e31dd3"
272
 checksum = "812e12b5285cc515a9c72a5c1d3b6d46a19dac5acfef5265968c166106e31dd3"
125
 
273
 
274
+[[package]]
275
+name = "block-buffer"
276
+version = "0.10.4"
277
+source = "registry+https://github.com/rust-lang/crates.io-index"
278
+checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71"
279
+dependencies = [
280
+ "generic-array",
281
+]
282
+
283
+[[package]]
284
+name = "blocking"
285
+version = "1.6.2"
286
+source = "registry+https://github.com/rust-lang/crates.io-index"
287
+checksum = "e83f8d02be6967315521be875afa792a316e28d57b5a2d401897e2a7921b7f21"
288
+dependencies = [
289
+ "async-channel",
290
+ "async-task",
291
+ "futures-io",
292
+ "futures-lite",
293
+ "piper",
294
+]
295
+
126
 [[package]]
296
 [[package]]
127
 name = "bytemuck"
297
 name = "bytemuck"
128
 version = "1.24.0"
298
 version = "1.24.0"
@@ -191,6 +361,12 @@ version = "1.0.4"
191
 source = "registry+https://github.com/rust-lang/crates.io-index"
361
 source = "registry+https://github.com/rust-lang/crates.io-index"
192
 checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801"
362
 checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801"
193
 
363
 
364
+[[package]]
365
+name = "cfg_aliases"
366
+version = "0.2.1"
367
+source = "registry+https://github.com/rust-lang/crates.io-index"
368
+checksum = "613afe47fcd5fac7ccf1db93babcb082c5994d996f20b8b159f2ad1658eb5724"
369
+
194
 [[package]]
370
 [[package]]
195
 name = "clang-sys"
371
 name = "clang-sys"
196
 version = "1.8.1"
372
 version = "1.8.1"
@@ -253,6 +429,24 @@ version = "1.0.4"
253
 source = "registry+https://github.com/rust-lang/crates.io-index"
429
 source = "registry+https://github.com/rust-lang/crates.io-index"
254
 checksum = "b05b61dc5112cbb17e4b6cd61790d9845d13888356391624cbe7e41efeac1e75"
430
 checksum = "b05b61dc5112cbb17e4b6cd61790d9845d13888356391624cbe7e41efeac1e75"
255
 
431
 
432
+[[package]]
433
+name = "concurrent-queue"
434
+version = "2.5.0"
435
+source = "registry+https://github.com/rust-lang/crates.io-index"
436
+checksum = "4ca0197aee26d1ae37445ee532fefce43251d24cc7c166799f4d46817f1d3973"
437
+dependencies = [
438
+ "crossbeam-utils",
439
+]
440
+
441
+[[package]]
442
+name = "cpufeatures"
443
+version = "0.2.17"
444
+source = "registry+https://github.com/rust-lang/crates.io-index"
445
+checksum = "59ed5838eebb26a2bb2e58f6d5b5316989ae9d08bab10e0e6d103e656d1b0280"
446
+dependencies = [
447
+ "libc",
448
+]
449
+
256
 [[package]]
450
 [[package]]
257
 name = "crc32fast"
451
 name = "crc32fast"
258
 version = "1.5.0"
452
 version = "1.5.0"
@@ -293,6 +487,26 @@ version = "0.2.4"
293
 source = "registry+https://github.com/rust-lang/crates.io-index"
487
 source = "registry+https://github.com/rust-lang/crates.io-index"
294
 checksum = "460fbee9c2c2f33933d720630a6a0bac33ba7053db5344fac858d4b8952d77d5"
488
 checksum = "460fbee9c2c2f33933d720630a6a0bac33ba7053db5344fac858d4b8952d77d5"
295
 
489
 
490
+[[package]]
491
+name = "crypto-common"
492
+version = "0.1.7"
493
+source = "registry+https://github.com/rust-lang/crates.io-index"
494
+checksum = "78c8292055d1c1df0cce5d180393dc8cce0abec0a7102adb6c7b1eef6016d60a"
495
+dependencies = [
496
+ "generic-array",
497
+ "typenum",
498
+]
499
+
500
+[[package]]
501
+name = "digest"
502
+version = "0.10.7"
503
+source = "registry+https://github.com/rust-lang/crates.io-index"
504
+checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292"
505
+dependencies = [
506
+ "block-buffer",
507
+ "crypto-common",
508
+]
509
+
296
 [[package]]
510
 [[package]]
297
 name = "dirs"
511
 name = "dirs"
298
 version = "6.0.0"
512
 version = "6.0.0"
@@ -320,6 +534,12 @@ version = "1.15.0"
320
 source = "registry+https://github.com/rust-lang/crates.io-index"
534
 source = "registry+https://github.com/rust-lang/crates.io-index"
321
 checksum = "48c757948c5ede0e46177b7add2e67155f70e33c07fea8284df6576da70b3719"
535
 checksum = "48c757948c5ede0e46177b7add2e67155f70e33c07fea8284df6576da70b3719"
322
 
536
 
537
+[[package]]
538
+name = "endi"
539
+version = "1.1.1"
540
+source = "registry+https://github.com/rust-lang/crates.io-index"
541
+checksum = "66b7e2430c6dff6a955451e2cfc438f09cea1965a9d6f87f7e3b90decc014099"
542
+
323
 [[package]]
543
 [[package]]
324
 name = "enum-repr"
544
 name = "enum-repr"
325
 version = "0.2.6"
545
 version = "0.2.6"
@@ -331,6 +551,27 @@ dependencies = [
331
  "syn 1.0.109",
551
  "syn 1.0.109",
332
 ]
552
 ]
333
 
553
 
554
+[[package]]
555
+name = "enumflags2"
556
+version = "0.7.12"
557
+source = "registry+https://github.com/rust-lang/crates.io-index"
558
+checksum = "1027f7680c853e056ebcec683615fb6fbbc07dbaa13b4d5d9442b146ded4ecef"
559
+dependencies = [
560
+ "enumflags2_derive",
561
+ "serde",
562
+]
563
+
564
+[[package]]
565
+name = "enumflags2_derive"
566
+version = "0.7.12"
567
+source = "registry+https://github.com/rust-lang/crates.io-index"
568
+checksum = "67c78a4d8fdf9953a5c9d458f9efe940fd97a0cab0941c075a813ac594733827"
569
+dependencies = [
570
+ "proc-macro2",
571
+ "quote",
572
+ "syn 2.0.114",
573
+]
574
+
334
 [[package]]
575
 [[package]]
335
 name = "equivalent"
576
 name = "equivalent"
336
 version = "1.0.2"
577
 version = "1.0.2"
@@ -347,6 +588,27 @@ dependencies = [
347
  "windows-sys 0.61.2",
588
  "windows-sys 0.61.2",
348
 ]
589
 ]
349
 
590
 
591
+[[package]]
592
+name = "event-listener"
593
+version = "5.4.1"
594
+source = "registry+https://github.com/rust-lang/crates.io-index"
595
+checksum = "e13b66accf52311f30a0db42147dadea9850cb48cd070028831ae5f5d4b856ab"
596
+dependencies = [
597
+ "concurrent-queue",
598
+ "parking",
599
+ "pin-project-lite",
600
+]
601
+
602
+[[package]]
603
+name = "event-listener-strategy"
604
+version = "0.5.4"
605
+source = "registry+https://github.com/rust-lang/crates.io-index"
606
+checksum = "8be9f3dfaaffdae2972880079a491a1a8bb7cbed0b8dd7a347f668b4150a3b93"
607
+dependencies = [
608
+ "event-listener",
609
+ "pin-project-lite",
610
+]
611
+
350
 [[package]]
612
 [[package]]
351
 name = "exr"
613
 name = "exr"
352
 version = "1.74.0"
614
 version = "1.74.0"
@@ -362,6 +624,12 @@ dependencies = [
362
  "zune-inflate",
624
  "zune-inflate",
363
 ]
625
 ]
364
 
626
 
627
+[[package]]
628
+name = "fastrand"
629
+version = "2.3.0"
630
+source = "registry+https://github.com/rust-lang/crates.io-index"
631
+checksum = "37909eebbb50d72f9059c3b6d82c0463f2ff062c9e95845c43a6c9c0355411be"
632
+
365
 [[package]]
633
 [[package]]
366
 name = "fdeflate"
634
 name = "fdeflate"
367
 version = "0.3.7"
635
 version = "0.3.7"
@@ -413,6 +681,19 @@ version = "0.3.31"
413
 source = "registry+https://github.com/rust-lang/crates.io-index"
681
 source = "registry+https://github.com/rust-lang/crates.io-index"
414
 checksum = "9e5c1b78ca4aae1ac06c48a526a655760685149f0d465d21f37abfe57ce075c6"
682
 checksum = "9e5c1b78ca4aae1ac06c48a526a655760685149f0d465d21f37abfe57ce075c6"
415
 
683
 
684
+[[package]]
685
+name = "futures-lite"
686
+version = "2.6.1"
687
+source = "registry+https://github.com/rust-lang/crates.io-index"
688
+checksum = "f78e10609fe0e0b3f4157ffab1876319b5b0db102a2c60dc4626306dc46b44ad"
689
+dependencies = [
690
+ "fastrand",
691
+ "futures-core",
692
+ "futures-io",
693
+ "parking",
694
+ "pin-project-lite",
695
+]
696
+
416
 [[package]]
697
 [[package]]
417
 name = "futures-macro"
698
 name = "futures-macro"
418
 version = "0.3.31"
699
 version = "0.3.31"
@@ -424,6 +705,12 @@ dependencies = [
424
  "syn 2.0.114",
705
  "syn 2.0.114",
425
 ]
706
 ]
426
 
707
 
708
+[[package]]
709
+name = "futures-sink"
710
+version = "0.3.31"
711
+source = "registry+https://github.com/rust-lang/crates.io-index"
712
+checksum = "e575fab7d1e0dcb8d0c7bcf9a63ee213816ab51902e6d244a95819acacf1d4f7"
713
+
427
 [[package]]
714
 [[package]]
428
 name = "futures-task"
715
 name = "futures-task"
429
 version = "0.3.31"
716
 version = "0.3.31"
@@ -437,8 +724,11 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
437
 checksum = "9fa08315bb612088cc391249efdc3bc77536f16c91f6cf495e6fbe85b20a4a81"
724
 checksum = "9fa08315bb612088cc391249efdc3bc77536f16c91f6cf495e6fbe85b20a4a81"
438
 dependencies = [
725
 dependencies = [
439
  "futures-core",
726
  "futures-core",
727
+ "futures-io",
440
  "futures-macro",
728
  "futures-macro",
729
+ "futures-sink",
441
  "futures-task",
730
  "futures-task",
731
+ "memchr",
442
  "pin-project-lite",
732
  "pin-project-lite",
443
  "pin-utils",
733
  "pin-utils",
444
  "slab",
734
  "slab",
@@ -452,7 +742,7 @@ dependencies = [
452
  "cairo-rs",
742
  "cairo-rs",
453
  "gardm-ipc",
743
  "gardm-ipc",
454
  "image",
744
  "image",
455
- "nix",
745
+ "nix 0.27.1",
456
  "pango",
746
  "pango",
457
  "pangocairo",
747
  "pangocairo",
458
  "rpassword 7.4.0",
748
  "rpassword 7.4.0",
@@ -485,7 +775,7 @@ dependencies = [
485
  "clap",
775
  "clap",
486
  "gardm-ipc",
776
  "gardm-ipc",
487
  "libc",
777
  "libc",
488
- "nix",
778
+ "nix 0.27.1",
489
  "pam-client",
779
  "pam-client",
490
  "sd-notify",
780
  "sd-notify",
491
  "serde",
781
  "serde",
@@ -496,6 +786,17 @@ dependencies = [
496
  "tracing",
786
  "tracing",
497
  "tracing-subscriber",
787
  "tracing-subscriber",
498
  "x11rb",
788
  "x11rb",
789
+ "zbus",
790
+]
791
+
792
+[[package]]
793
+name = "generic-array"
794
+version = "0.14.7"
795
+source = "registry+https://github.com/rust-lang/crates.io-index"
796
+checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a"
797
+dependencies = [
798
+ "typenum",
799
+ "version_check",
499
 ]
800
 ]
500
 
801
 
501
 [[package]]
802
 [[package]]
@@ -519,6 +820,18 @@ dependencies = [
519
  "wasi",
820
  "wasi",
520
 ]
821
 ]
521
 
822
 
823
+[[package]]
824
+name = "getrandom"
825
+version = "0.3.4"
826
+source = "registry+https://github.com/rust-lang/crates.io-index"
827
+checksum = "899def5c37c4fd7b2664648c28120ecec138e4d395b459e5ca34f9cce2dd77fd"
828
+dependencies = [
829
+ "cfg-if",
830
+ "libc",
831
+ "r-efi",
832
+ "wasip2",
833
+]
834
+
522
 [[package]]
835
 [[package]]
523
 name = "gif"
836
 name = "gif"
524
 version = "0.13.3"
837
 version = "0.13.3"
@@ -591,7 +904,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
591
 checksum = "0bb0228f477c0900c880fd78c8759b95c7636dbd7842707f49e132378aa2acdc"
904
 checksum = "0bb0228f477c0900c880fd78c8759b95c7636dbd7842707f49e132378aa2acdc"
592
 dependencies = [
905
 dependencies = [
593
  "heck 0.4.1",
906
  "heck 0.4.1",
594
- "proc-macro-crate",
907
+ "proc-macro-crate 2.0.2",
595
  "proc-macro-error",
908
  "proc-macro-error",
596
  "proc-macro2",
909
  "proc-macro2",
597
  "quote",
910
  "quote",
@@ -654,6 +967,18 @@ version = "0.5.0"
654
 source = "registry+https://github.com/rust-lang/crates.io-index"
967
 source = "registry+https://github.com/rust-lang/crates.io-index"
655
 checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea"
968
 checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea"
656
 
969
 
970
+[[package]]
971
+name = "hermit-abi"
972
+version = "0.5.2"
973
+source = "registry+https://github.com/rust-lang/crates.io-index"
974
+checksum = "fc0fef456e4baa96da950455cd02c081ca953b141298e41db3fc7e36b1da849c"
975
+
976
+[[package]]
977
+name = "hex"
978
+version = "0.4.3"
979
+source = "registry+https://github.com/rust-lang/crates.io-index"
980
+checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70"
981
+
657
 [[package]]
982
 [[package]]
658
 name = "image"
983
 name = "image"
659
 version = "0.24.9"
984
 version = "0.24.9"
@@ -782,6 +1107,15 @@ version = "2.7.6"
782
 source = "registry+https://github.com/rust-lang/crates.io-index"
1107
 source = "registry+https://github.com/rust-lang/crates.io-index"
783
 checksum = "f52b00d39961fc5b2736ea853c9cc86238e165017a493d1d5c8eac6bdc4cc273"
1108
 checksum = "f52b00d39961fc5b2736ea853c9cc86238e165017a493d1d5c8eac6bdc4cc273"
784
 
1109
 
1110
+[[package]]
1111
+name = "memoffset"
1112
+version = "0.9.1"
1113
+source = "registry+https://github.com/rust-lang/crates.io-index"
1114
+checksum = "488016bfae457b036d996092f6cb448677611ce4449e970ceaf42695203f218a"
1115
+dependencies = [
1116
+ "autocfg",
1117
+]
1118
+
785
 [[package]]
1119
 [[package]]
786
 name = "minimal-lexical"
1120
 name = "minimal-lexical"
787
 version = "0.2.1"
1121
 version = "0.2.1"
@@ -820,6 +1154,19 @@ dependencies = [
820
  "libc",
1154
  "libc",
821
 ]
1155
 ]
822
 
1156
 
1157
+[[package]]
1158
+name = "nix"
1159
+version = "0.29.0"
1160
+source = "registry+https://github.com/rust-lang/crates.io-index"
1161
+checksum = "71e2746dc3a24dd78b3cfcb7be93368c6de9963d30f43a6a73998a9cf4b17b46"
1162
+dependencies = [
1163
+ "bitflags 2.10.0",
1164
+ "cfg-if",
1165
+ "cfg_aliases",
1166
+ "libc",
1167
+ "memoffset",
1168
+]
1169
+
823
 [[package]]
1170
 [[package]]
824
 name = "nom"
1171
 name = "nom"
825
 version = "7.1.3"
1172
 version = "7.1.3"
@@ -866,6 +1213,16 @@ version = "0.2.0"
866
 source = "registry+https://github.com/rust-lang/crates.io-index"
1213
 source = "registry+https://github.com/rust-lang/crates.io-index"
867
 checksum = "04744f49eae99ab78e0d5c0b603ab218f515ea8cfe5a456d7629ad883a3b6e7d"
1214
 checksum = "04744f49eae99ab78e0d5c0b603ab218f515ea8cfe5a456d7629ad883a3b6e7d"
868
 
1215
 
1216
+[[package]]
1217
+name = "ordered-stream"
1218
+version = "0.2.0"
1219
+source = "registry+https://github.com/rust-lang/crates.io-index"
1220
+checksum = "9aa2b01e1d916879f73a53d01d1d6cee68adbb31d6d9177a8cfce093cced1d50"
1221
+dependencies = [
1222
+ "futures-core",
1223
+ "pin-project-lite",
1224
+]
1225
+
869
 [[package]]
1226
 [[package]]
870
 name = "pam-client"
1227
 name = "pam-client"
871
 version = "0.5.0"
1228
 version = "0.5.0"
@@ -941,6 +1298,12 @@ dependencies = [
941
  "system-deps",
1298
  "system-deps",
942
 ]
1299
 ]
943
 
1300
 
1301
+[[package]]
1302
+name = "parking"
1303
+version = "2.2.1"
1304
+source = "registry+https://github.com/rust-lang/crates.io-index"
1305
+checksum = "f38d5652c16fde515bb1ecef450ab0f6a219d619a7274976324d5e377f7dceba"
1306
+
944
 [[package]]
1307
 [[package]]
945
 name = "parking_lot"
1308
 name = "parking_lot"
946
 version = "0.12.5"
1309
 version = "0.12.5"
@@ -976,6 +1339,17 @@ version = "0.1.0"
976
 source = "registry+https://github.com/rust-lang/crates.io-index"
1339
 source = "registry+https://github.com/rust-lang/crates.io-index"
977
 checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184"
1340
 checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184"
978
 
1341
 
1342
+[[package]]
1343
+name = "piper"
1344
+version = "0.2.4"
1345
+source = "registry+https://github.com/rust-lang/crates.io-index"
1346
+checksum = "96c8c490f422ef9a4efd2cb5b42b76c8613d7e7dfc1caf667b8a3350a5acc066"
1347
+dependencies = [
1348
+ "atomic-waker",
1349
+ "fastrand",
1350
+ "futures-io",
1351
+]
1352
+
979
 [[package]]
1353
 [[package]]
980
 name = "pkg-config"
1354
 name = "pkg-config"
981
 version = "0.3.32"
1355
 version = "0.3.32"
@@ -995,14 +1369,46 @@ dependencies = [
995
  "miniz_oxide",
1369
  "miniz_oxide",
996
 ]
1370
 ]
997
 
1371
 
1372
+[[package]]
1373
+name = "polling"
1374
+version = "3.11.0"
1375
+source = "registry+https://github.com/rust-lang/crates.io-index"
1376
+checksum = "5d0e4f59085d47d8241c88ead0f274e8a0cb551f3625263c05eb8dd897c34218"
1377
+dependencies = [
1378
+ "cfg-if",
1379
+ "concurrent-queue",
1380
+ "hermit-abi",
1381
+ "pin-project-lite",
1382
+ "rustix",
1383
+ "windows-sys 0.61.2",
1384
+]
1385
+
1386
+[[package]]
1387
+name = "ppv-lite86"
1388
+version = "0.2.21"
1389
+source = "registry+https://github.com/rust-lang/crates.io-index"
1390
+checksum = "85eae3c4ed2f50dcfe72643da4befc30deadb458a9b590d720cde2f2b1e97da9"
1391
+dependencies = [
1392
+ "zerocopy",
1393
+]
1394
+
998
 [[package]]
1395
 [[package]]
999
 name = "proc-macro-crate"
1396
 name = "proc-macro-crate"
1000
 version = "2.0.2"
1397
 version = "2.0.2"
1001
 source = "registry+https://github.com/rust-lang/crates.io-index"
1398
 source = "registry+https://github.com/rust-lang/crates.io-index"
1002
 checksum = "b00f26d3400549137f92511a46ac1cd8ce37cb5598a96d382381458b992a5d24"
1399
 checksum = "b00f26d3400549137f92511a46ac1cd8ce37cb5598a96d382381458b992a5d24"
1003
 dependencies = [
1400
 dependencies = [
1004
- "toml_datetime",
1401
+ "toml_datetime 0.6.3",
1005
- "toml_edit",
1402
+ "toml_edit 0.20.2",
1403
+]
1404
+
1405
+[[package]]
1406
+name = "proc-macro-crate"
1407
+version = "3.4.0"
1408
+source = "registry+https://github.com/rust-lang/crates.io-index"
1409
+checksum = "219cb19e96be00ab2e37d6e299658a0cfa83e52429179969b0f0121b4ac46983"
1410
+dependencies = [
1411
+ "toml_edit 0.23.10+spec-1.0.0",
1006
 ]
1412
 ]
1007
 
1413
 
1008
 [[package]]
1414
 [[package]]
@@ -1056,6 +1462,42 @@ dependencies = [
1056
  "proc-macro2",
1462
  "proc-macro2",
1057
 ]
1463
 ]
1058
 
1464
 
1465
+[[package]]
1466
+name = "r-efi"
1467
+version = "5.3.0"
1468
+source = "registry+https://github.com/rust-lang/crates.io-index"
1469
+checksum = "69cdb34c158ceb288df11e18b4bd39de994f6657d83847bdffdbd7f346754b0f"
1470
+
1471
+[[package]]
1472
+name = "rand"
1473
+version = "0.8.5"
1474
+source = "registry+https://github.com/rust-lang/crates.io-index"
1475
+checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404"
1476
+dependencies = [
1477
+ "libc",
1478
+ "rand_chacha",
1479
+ "rand_core",
1480
+]
1481
+
1482
+[[package]]
1483
+name = "rand_chacha"
1484
+version = "0.3.1"
1485
+source = "registry+https://github.com/rust-lang/crates.io-index"
1486
+checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88"
1487
+dependencies = [
1488
+ "ppv-lite86",
1489
+ "rand_core",
1490
+]
1491
+
1492
+[[package]]
1493
+name = "rand_core"
1494
+version = "0.6.4"
1495
+source = "registry+https://github.com/rust-lang/crates.io-index"
1496
+checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c"
1497
+dependencies = [
1498
+ "getrandom 0.2.17",
1499
+]
1500
+
1059
 [[package]]
1501
 [[package]]
1060
 name = "rayon"
1502
 name = "rayon"
1061
 version = "1.11.0"
1503
 version = "1.11.0"
@@ -1091,7 +1533,7 @@ version = "0.5.2"
1091
 source = "registry+https://github.com/rust-lang/crates.io-index"
1533
 source = "registry+https://github.com/rust-lang/crates.io-index"
1092
 checksum = "a4e608c6638b9c18977b00b475ac1f28d14e84b27d8d42f70e0bf1e3dec127ac"
1534
 checksum = "a4e608c6638b9c18977b00b475ac1f28d14e84b27d8d42f70e0bf1e3dec127ac"
1093
 dependencies = [
1535
 dependencies = [
1094
- "getrandom",
1536
+ "getrandom 0.2.17",
1095
  "libredox",
1537
  "libredox",
1096
  "thiserror 2.0.17",
1538
  "thiserror 2.0.17",
1097
 ]
1539
 ]
@@ -1241,6 +1683,17 @@ dependencies = [
1241
  "zmij",
1683
  "zmij",
1242
 ]
1684
 ]
1243
 
1685
 
1686
+[[package]]
1687
+name = "serde_repr"
1688
+version = "0.1.20"
1689
+source = "registry+https://github.com/rust-lang/crates.io-index"
1690
+checksum = "175ee3e80ae9982737ca543e96133087cbd9a485eecc3bc4de9c1a37b47ea59c"
1691
+dependencies = [
1692
+ "proc-macro2",
1693
+ "quote",
1694
+ "syn 2.0.114",
1695
+]
1696
+
1244
 [[package]]
1697
 [[package]]
1245
 name = "serde_spanned"
1698
 name = "serde_spanned"
1246
 version = "0.6.9"
1699
 version = "0.6.9"
@@ -1250,6 +1703,17 @@ dependencies = [
1250
  "serde",
1703
  "serde",
1251
 ]
1704
 ]
1252
 
1705
 
1706
+[[package]]
1707
+name = "sha1"
1708
+version = "0.10.6"
1709
+source = "registry+https://github.com/rust-lang/crates.io-index"
1710
+checksum = "e3bf829a2d51ab4a5ddf1352d8470c140cadc8301b2ae1789db023f01cedd6ba"
1711
+dependencies = [
1712
+ "cfg-if",
1713
+ "cpufeatures",
1714
+ "digest",
1715
+]
1716
+
1253
 [[package]]
1717
 [[package]]
1254
 name = "sharded-slab"
1718
 name = "sharded-slab"
1255
 version = "0.1.7"
1719
 version = "0.1.7"
@@ -1312,6 +1776,12 @@ dependencies = [
1312
  "windows-sys 0.60.2",
1776
  "windows-sys 0.60.2",
1313
 ]
1777
 ]
1314
 
1778
 
1779
+[[package]]
1780
+name = "static_assertions"
1781
+version = "1.1.0"
1782
+source = "registry+https://github.com/rust-lang/crates.io-index"
1783
+checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f"
1784
+
1315
 [[package]]
1785
 [[package]]
1316
 name = "strsim"
1786
 name = "strsim"
1317
 version = "0.11.1"
1787
 version = "0.11.1"
@@ -1359,6 +1829,19 @@ version = "0.12.16"
1359
 source = "registry+https://github.com/rust-lang/crates.io-index"
1829
 source = "registry+https://github.com/rust-lang/crates.io-index"
1360
 checksum = "61c41af27dd6d1e27b1b16b489db798443478cef1f06a660c96db617ba5de3b1"
1830
 checksum = "61c41af27dd6d1e27b1b16b489db798443478cef1f06a660c96db617ba5de3b1"
1361
 
1831
 
1832
+[[package]]
1833
+name = "tempfile"
1834
+version = "3.24.0"
1835
+source = "registry+https://github.com/rust-lang/crates.io-index"
1836
+checksum = "655da9c7eb6305c55742045d5a8d2037996d61d8de95806335c7c86ce0f82e9c"
1837
+dependencies = [
1838
+ "fastrand",
1839
+ "getrandom 0.3.4",
1840
+ "once_cell",
1841
+ "rustix",
1842
+ "windows-sys 0.61.2",
1843
+]
1844
+
1362
 [[package]]
1845
 [[package]]
1363
 name = "thiserror"
1846
 name = "thiserror"
1364
 version = "1.0.69"
1847
 version = "1.0.69"
@@ -1455,8 +1938,8 @@ checksum = "185d8ab0dfbb35cf1399a6344d8484209c088f75f8f68230da55d48d95d43e3d"
1455
 dependencies = [
1938
 dependencies = [
1456
  "serde",
1939
  "serde",
1457
  "serde_spanned",
1940
  "serde_spanned",
1458
- "toml_datetime",
1941
+ "toml_datetime 0.6.3",
1459
- "toml_edit",
1942
+ "toml_edit 0.20.2",
1460
 ]
1943
 ]
1461
 
1944
 
1462
 [[package]]
1945
 [[package]]
@@ -1468,6 +1951,15 @@ dependencies = [
1468
  "serde",
1951
  "serde",
1469
 ]
1952
 ]
1470
 
1953
 
1954
+[[package]]
1955
+name = "toml_datetime"
1956
+version = "0.7.5+spec-1.1.0"
1957
+source = "registry+https://github.com/rust-lang/crates.io-index"
1958
+checksum = "92e1cfed4a3038bc5a127e35a2d360f145e1f4b971b551a2ba5fd7aedf7e1347"
1959
+dependencies = [
1960
+ "serde_core",
1961
+]
1962
+
1471
 [[package]]
1963
 [[package]]
1472
 name = "toml_edit"
1964
 name = "toml_edit"
1473
 version = "0.20.2"
1965
 version = "0.20.2"
@@ -1477,8 +1969,29 @@ dependencies = [
1477
  "indexmap",
1969
  "indexmap",
1478
  "serde",
1970
  "serde",
1479
  "serde_spanned",
1971
  "serde_spanned",
1480
- "toml_datetime",
1972
+ "toml_datetime 0.6.3",
1481
- "winnow",
1973
+ "winnow 0.5.40",
1974
+]
1975
+
1976
+[[package]]
1977
+name = "toml_edit"
1978
+version = "0.23.10+spec-1.0.0"
1979
+source = "registry+https://github.com/rust-lang/crates.io-index"
1980
+checksum = "84c8b9f757e028cee9fa244aea147aab2a9ec09d5325a9b01e0a49730c2b5269"
1981
+dependencies = [
1982
+ "indexmap",
1983
+ "toml_datetime 0.7.5+spec-1.1.0",
1984
+ "toml_parser",
1985
+ "winnow 0.7.14",
1986
+]
1987
+
1988
+[[package]]
1989
+name = "toml_parser"
1990
+version = "1.0.6+spec-1.1.0"
1991
+source = "registry+https://github.com/rust-lang/crates.io-index"
1992
+checksum = "a3198b4b0a8e11f09dd03e133c0280504d0801269e9afa46362ffde1cbeebf44"
1993
+dependencies = [
1994
+ "winnow 0.7.14",
1482
 ]
1995
 ]
1483
 
1996
 
1484
 [[package]]
1997
 [[package]]
@@ -1542,6 +2055,23 @@ dependencies = [
1542
  "tracing-log",
2055
  "tracing-log",
1543
 ]
2056
 ]
1544
 
2057
 
2058
+[[package]]
2059
+name = "typenum"
2060
+version = "1.19.0"
2061
+source = "registry+https://github.com/rust-lang/crates.io-index"
2062
+checksum = "562d481066bde0658276a35467c4af00bdc6ee726305698a55b86e61d7ad82bb"
2063
+
2064
+[[package]]
2065
+name = "uds_windows"
2066
+version = "1.1.0"
2067
+source = "registry+https://github.com/rust-lang/crates.io-index"
2068
+checksum = "89daebc3e6fd160ac4aa9fc8b3bf71e1f74fbf92367ae71fb83a037e8bf164b9"
2069
+dependencies = [
2070
+ "memoffset",
2071
+ "tempfile",
2072
+ "winapi",
2073
+]
2074
+
1545
 [[package]]
2075
 [[package]]
1546
 name = "unicode-ident"
2076
 name = "unicode-ident"
1547
 version = "1.0.22"
2077
 version = "1.0.22"
@@ -1578,6 +2108,15 @@ version = "0.11.1+wasi-snapshot-preview1"
1578
 source = "registry+https://github.com/rust-lang/crates.io-index"
2108
 source = "registry+https://github.com/rust-lang/crates.io-index"
1579
 checksum = "ccf3ec651a847eb01de73ccad15eb7d99f80485de043efb2f370cd654f4ea44b"
2109
 checksum = "ccf3ec651a847eb01de73ccad15eb7d99f80485de043efb2f370cd654f4ea44b"
1580
 
2110
 
2111
+[[package]]
2112
+name = "wasip2"
2113
+version = "1.0.1+wasi-0.2.4"
2114
+source = "registry+https://github.com/rust-lang/crates.io-index"
2115
+checksum = "0562428422c63773dad2c345a1882263bbf4d65cf3f42e90921f787ef5ad58e7"
2116
+dependencies = [
2117
+ "wit-bindgen",
2118
+]
2119
+
1581
 [[package]]
2120
 [[package]]
1582
 name = "weezl"
2121
 name = "weezl"
1583
 version = "0.1.12"
2122
 version = "0.1.12"
@@ -1786,6 +2325,21 @@ dependencies = [
1786
  "memchr",
2325
  "memchr",
1787
 ]
2326
 ]
1788
 
2327
 
2328
+[[package]]
2329
+name = "winnow"
2330
+version = "0.7.14"
2331
+source = "registry+https://github.com/rust-lang/crates.io-index"
2332
+checksum = "5a5364e9d77fcdeeaa6062ced926ee3381faa2ee02d3eb83a5c27a8825540829"
2333
+dependencies = [
2334
+ "memchr",
2335
+]
2336
+
2337
+[[package]]
2338
+name = "wit-bindgen"
2339
+version = "0.46.0"
2340
+source = "registry+https://github.com/rust-lang/crates.io-index"
2341
+checksum = "f17a85883d4e6d00e8a97c586de764dabcc06133f7f1d55dce5cdc070ad7fe59"
2342
+
1789
 [[package]]
2343
 [[package]]
1790
 name = "x11rb"
2344
 name = "x11rb"
1791
 version = "0.13.2"
2345
 version = "0.13.2"
@@ -1805,6 +2359,78 @@ version = "0.13.2"
1805
 source = "registry+https://github.com/rust-lang/crates.io-index"
2359
 source = "registry+https://github.com/rust-lang/crates.io-index"
1806
 checksum = "ea6fc2961e4ef194dcbfe56bb845534d0dc8098940c7e5c012a258bfec6701bd"
2360
 checksum = "ea6fc2961e4ef194dcbfe56bb845534d0dc8098940c7e5c012a258bfec6701bd"
1807
 
2361
 
2362
+[[package]]
2363
+name = "xdg-home"
2364
+version = "1.3.0"
2365
+source = "registry+https://github.com/rust-lang/crates.io-index"
2366
+checksum = "ec1cdab258fb55c0da61328dc52c8764709b249011b2cad0454c72f0bf10a1f6"
2367
+dependencies = [
2368
+ "libc",
2369
+ "windows-sys 0.59.0",
2370
+]
2371
+
2372
+[[package]]
2373
+name = "zbus"
2374
+version = "4.4.0"
2375
+source = "registry+https://github.com/rust-lang/crates.io-index"
2376
+checksum = "bb97012beadd29e654708a0fdb4c84bc046f537aecfde2c3ee0a9e4b4d48c725"
2377
+dependencies = [
2378
+ "async-broadcast",
2379
+ "async-executor",
2380
+ "async-fs",
2381
+ "async-io",
2382
+ "async-lock",
2383
+ "async-process",
2384
+ "async-recursion",
2385
+ "async-task",
2386
+ "async-trait",
2387
+ "blocking",
2388
+ "enumflags2",
2389
+ "event-listener",
2390
+ "futures-core",
2391
+ "futures-sink",
2392
+ "futures-util",
2393
+ "hex",
2394
+ "nix 0.29.0",
2395
+ "ordered-stream",
2396
+ "rand",
2397
+ "serde",
2398
+ "serde_repr",
2399
+ "sha1",
2400
+ "static_assertions",
2401
+ "tracing",
2402
+ "uds_windows",
2403
+ "windows-sys 0.52.0",
2404
+ "xdg-home",
2405
+ "zbus_macros",
2406
+ "zbus_names",
2407
+ "zvariant",
2408
+]
2409
+
2410
+[[package]]
2411
+name = "zbus_macros"
2412
+version = "4.4.0"
2413
+source = "registry+https://github.com/rust-lang/crates.io-index"
2414
+checksum = "267db9407081e90bbfa46d841d3cbc60f59c0351838c4bc65199ecd79ab1983e"
2415
+dependencies = [
2416
+ "proc-macro-crate 3.4.0",
2417
+ "proc-macro2",
2418
+ "quote",
2419
+ "syn 2.0.114",
2420
+ "zvariant_utils",
2421
+]
2422
+
2423
+[[package]]
2424
+name = "zbus_names"
2425
+version = "3.0.0"
2426
+source = "registry+https://github.com/rust-lang/crates.io-index"
2427
+checksum = "4b9b1fef7d021261cc16cba64c351d291b715febe0fa10dc3a443ac5a5022e6c"
2428
+dependencies = [
2429
+ "serde",
2430
+ "static_assertions",
2431
+ "zvariant",
2432
+]
2433
+
1808
 [[package]]
2434
 [[package]]
1809
 name = "zerocopy"
2435
 name = "zerocopy"
1810
 version = "0.8.33"
2436
 version = "0.8.33"
@@ -1839,3 +2465,40 @@ checksum = "73ab332fe2f6680068f3582b16a24f90ad7096d5d39b974d1c0aff0125116f02"
1839
 dependencies = [
2465
 dependencies = [
1840
  "simd-adler32",
2466
  "simd-adler32",
1841
 ]
2467
 ]
2468
+
2469
+[[package]]
2470
+name = "zvariant"
2471
+version = "4.2.0"
2472
+source = "registry+https://github.com/rust-lang/crates.io-index"
2473
+checksum = "2084290ab9a1c471c38fc524945837734fbf124487e105daec2bb57fd48c81fe"
2474
+dependencies = [
2475
+ "endi",
2476
+ "enumflags2",
2477
+ "serde",
2478
+ "static_assertions",
2479
+ "zvariant_derive",
2480
+]
2481
+
2482
+[[package]]
2483
+name = "zvariant_derive"
2484
+version = "4.2.0"
2485
+source = "registry+https://github.com/rust-lang/crates.io-index"
2486
+checksum = "73e2ba546bda683a90652bac4a279bc146adad1386f25379cf73200d2002c449"
2487
+dependencies = [
2488
+ "proc-macro-crate 3.4.0",
2489
+ "proc-macro2",
2490
+ "quote",
2491
+ "syn 2.0.114",
2492
+ "zvariant_utils",
2493
+]
2494
+
2495
+[[package]]
2496
+name = "zvariant_utils"
2497
+version = "2.1.0"
2498
+source = "registry+https://github.com/rust-lang/crates.io-index"
2499
+checksum = "c51bcff7cc3dbb5055396bcf774748c3dab426b4b8659046963523cee4808340"
2500
+dependencies = [
2501
+ "proc-macro2",
2502
+ "quote",
2503
+ "syn 2.0.114",
2504
+]
etc/gardm.servicemodified
@@ -1,8 +1,11 @@
1
 [Unit]
1
 [Unit]
2
 Description=gar Display Manager
2
 Description=gar Display Manager
3
 Documentation=https://github.com/mfwolffe/gardesk
3
 Documentation=https://github.com/mfwolffe/gardesk
4
-After=systemd-user-sessions.service getty@tty1.service plymouth-quit.service
4
+After=systemd-user-sessions.service getty@tty1.service plymouth-quit.service systemd-logind.service
5
 Conflicts=getty@tty1.service
5
 Conflicts=getty@tty1.service
6
+PartOf=graphical.target
7
+StartLimitIntervalSec=30
8
+StartLimitBurst=2
6
 
9
 
7
 [Service]
10
 [Service]
8
 Type=notify
11
 Type=notify
@@ -10,16 +13,10 @@ ExecStart=/usr/bin/gardmd
10
 ExecReload=/bin/kill -HUP $MAINPID
13
 ExecReload=/bin/kill -HUP $MAINPID
11
 Restart=always
14
 Restart=always
12
 RestartSec=1
15
 RestartSec=1
16
+EnvironmentFile=-/etc/sysconfig/gardm
13
 
17
 
14
-# Security hardening
18
+# Minimal security hardening (display managers need broad access)
15
-NoNewPrivileges=no
19
+PrivateTmp=no
16
-ProtectSystem=strict
17
-ProtectHome=read-only
18
-PrivateTmp=yes
19
-ReadWritePaths=/run
20
-
21
-# PAM needs access to various system files
22
-ReadOnlyPaths=/etc/passwd /etc/shadow /etc/group /etc/pam.d
23
 
20
 
24
 [Install]
21
 [Install]
25
 Alias=display-manager.service
22
 Alias=display-manager.service
etc/pam.d/gardmmodified
@@ -1,7 +1,23 @@
1
 #%PAM-1.0
1
 #%PAM-1.0
2
-auth       required     pam_securetty.so
2
+# PAM configuration for gardm display manager
3
-auth       requisite    pam_nologin.so
3
+# Based on SDDM's Fedora configuration
4
-auth       include      system-local-login
4
+
5
-account    include      system-local-login
5
+# SELinux permit (Fedora-specific)
6
-session    include      system-local-login
6
+auth     [success=done ignore=ignore default=bad] pam_selinux_permit.so
7
-password   include      system-local-login
7
+auth        substack      password-auth
8
+-auth       optional      pam_gnome_keyring.so
9
+auth        include       postlogin
10
+
11
+account     required      pam_nologin.so
12
+account     include       password-auth
13
+
14
+password    include       password-auth
15
+
16
+session     required      pam_selinux.so close
17
+session     required      pam_loginuid.so
18
+session     required      pam_selinux.so open
19
+session     optional      pam_keyinit.so force revoke
20
+session     required      pam_namespace.so
21
+session     include       password-auth
22
+-session    optional      pam_gnome_keyring.so auto_start
23
+session     include       postlogin
gardmd/Cargo.tomlmodified
@@ -25,3 +25,4 @@ x11rb = { workspace = true }
25
 clap = { workspace = true }
25
 clap = { workspace = true }
26
 libc = "0.2"
26
 libc = "0.2"
27
 sd-notify = "0.4"
27
 sd-notify = "0.4"
28
+zbus = "4"
gardmd/src/lib.rsmodified
@@ -6,6 +6,7 @@ pub mod auth;
6
 pub mod config;
6
 pub mod config;
7
 pub mod greeter;
7
 pub mod greeter;
8
 pub mod ipc;
8
 pub mod ipc;
9
+pub mod power;
9
 pub mod session;
10
 pub mod session;
10
 pub mod sessions;
11
 pub mod sessions;
11
 pub mod vt;
12
 pub mod vt;
gardmd/src/main.rsmodified
@@ -309,33 +309,41 @@ async fn handle_greeter_request(
309
 
309
 
310
         Request::Shutdown => {
310
         Request::Shutdown => {
311
             tracing::info!("Shutdown requested");
311
             tracing::info!("Shutdown requested");
312
-            // TODO: Implement via logind
312
+            match gardmd::power::execute_async(gardmd::power::PowerAction::Shutdown).await {
313
-            (
313
+                Ok(()) => (Response::Success, None),
314
-                Response::Error {
314
+                Err(e) => (
315
-                    message: "Shutdown not yet implemented".to_string(),
315
+                    Response::Error {
316
-                },
316
+                        message: format!("Shutdown failed: {}", e),
317
-                None,
317
+                    },
318
-            )
318
+                    None,
319
+                ),
320
+            }
319
         }
321
         }
320
 
322
 
321
         Request::Reboot => {
323
         Request::Reboot => {
322
             tracing::info!("Reboot requested");
324
             tracing::info!("Reboot requested");
323
-            (
325
+            match gardmd::power::execute_async(gardmd::power::PowerAction::Reboot).await {
324
-                Response::Error {
326
+                Ok(()) => (Response::Success, None),
325
-                    message: "Reboot not yet implemented".to_string(),
327
+                Err(e) => (
326
-                },
328
+                    Response::Error {
327
-                None,
329
+                        message: format!("Reboot failed: {}", e),
328
-            )
330
+                    },
331
+                    None,
332
+                ),
333
+            }
329
         }
334
         }
330
 
335
 
331
         Request::Suspend => {
336
         Request::Suspend => {
332
             tracing::info!("Suspend requested");
337
             tracing::info!("Suspend requested");
333
-            (
338
+            match gardmd::power::execute_async(gardmd::power::PowerAction::Suspend).await {
334
-                Response::Error {
339
+                Ok(()) => (Response::Success, None),
335
-                    message: "Suspend not yet implemented".to_string(),
340
+                Err(e) => (
336
-                },
341
+                    Response::Error {
337
-                None,
342
+                        message: format!("Suspend failed: {}", e),
338
-            )
343
+                    },
344
+                    None,
345
+                ),
346
+            }
339
         }
347
         }
340
 
348
 
341
         Request::ListSessions => {
349
         Request::ListSessions => {
gardmd/src/power.rsadded
@@ -0,0 +1,91 @@
1
+//! Power management via systemd-logind
2
+//!
3
+//! Implements shutdown, reboot, and suspend via D-Bus calls to logind.
4
+
5
+use anyhow::{Context, Result};
6
+use zbus::blocking::Connection;
7
+
8
+/// Power action to perform
9
+#[derive(Debug, Clone, Copy)]
10
+pub enum PowerAction {
11
+    Shutdown,
12
+    Reboot,
13
+    Suspend,
14
+}
15
+
16
+impl PowerAction {
17
+    /// Get the logind method name for this action
18
+    fn method_name(&self) -> &'static str {
19
+        match self {
20
+            PowerAction::Shutdown => "PowerOff",
21
+            PowerAction::Reboot => "Reboot",
22
+            PowerAction::Suspend => "Suspend",
23
+        }
24
+    }
25
+}
26
+
27
+/// Execute a power action via logind
28
+pub fn execute(action: PowerAction) -> Result<()> {
29
+    let conn = Connection::system().context("Failed to connect to system D-Bus")?;
30
+
31
+    // Call org.freedesktop.login1.Manager.<Action>(interactive: bool)
32
+    // interactive=false means no polkit prompt
33
+    conn.call_method(
34
+        Some("org.freedesktop.login1"),
35
+        "/org/freedesktop/login1",
36
+        Some("org.freedesktop.login1.Manager"),
37
+        action.method_name(),
38
+        &(false,), // interactive = false
39
+    )
40
+    .context(format!("Failed to execute {:?}", action))?;
41
+
42
+    Ok(())
43
+}
44
+
45
+/// Async version of execute using zbus async API
46
+pub async fn execute_async(action: PowerAction) -> Result<()> {
47
+    let conn = zbus::Connection::system()
48
+        .await
49
+        .context("Failed to connect to system D-Bus")?;
50
+
51
+    conn.call_method(
52
+        Some("org.freedesktop.login1"),
53
+        "/org/freedesktop/login1",
54
+        Some("org.freedesktop.login1.Manager"),
55
+        action.method_name(),
56
+        &(false,),
57
+    )
58
+    .await
59
+    .context(format!("Failed to execute {:?}", action))?;
60
+
61
+    Ok(())
62
+}
63
+
64
+/// Check if a power action is allowed (can be performed without authentication)
65
+pub async fn can_execute(action: PowerAction) -> Result<bool> {
66
+    let conn = zbus::Connection::system()
67
+        .await
68
+        .context("Failed to connect to system D-Bus")?;
69
+
70
+    let can_method = match action {
71
+        PowerAction::Shutdown => "CanPowerOff",
72
+        PowerAction::Reboot => "CanReboot",
73
+        PowerAction::Suspend => "CanSuspend",
74
+    };
75
+
76
+    let reply: zbus::Message = conn
77
+        .call_method(
78
+            Some("org.freedesktop.login1"),
79
+            "/org/freedesktop/login1",
80
+            Some("org.freedesktop.login1.Manager"),
81
+            can_method,
82
+            &(),
83
+        )
84
+        .await
85
+        .context(format!("Failed to check {:?} capability", action))?;
86
+
87
+    let result: String = reply.body().deserialize().context("Failed to parse reply")?;
88
+
89
+    // Returns "yes", "no", "challenge" (needs auth), or "na" (not applicable)
90
+    Ok(result == "yes")
91
+}
scripts/install.shadded
@@ -0,0 +1,87 @@
1
+#!/bin/bash
2
+# gardm installation script
3
+# Installs gardm (gar display manager) system-wide
4
+
5
+set -e
6
+
7
+# Colors for output
8
+RED='\033[0;31m'
9
+GREEN='\033[0;32m'
10
+YELLOW='\033[1;33m'
11
+NC='\033[0m' # No Color
12
+
13
+log_info() {
14
+    echo -e "${GREEN}[INFO]${NC} $1"
15
+}
16
+
17
+log_warn() {
18
+    echo -e "${YELLOW}[WARN]${NC} $1"
19
+}
20
+
21
+log_error() {
22
+    echo -e "${RED}[ERROR]${NC} $1"
23
+}
24
+
25
+# Check if running as root
26
+if [ "$EUID" -ne 0 ]; then
27
+    log_error "Please run as root (sudo ./install.sh)"
28
+    exit 1
29
+fi
30
+
31
+SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
32
+PROJECT_DIR="$(dirname "$SCRIPT_DIR")"
33
+
34
+log_info "Installing gardm from $PROJECT_DIR"
35
+
36
+# Build release binaries
37
+log_info "Building release binaries..."
38
+cd "$PROJECT_DIR"
39
+cargo build --release -p gardmd -p gardm-greeter
40
+
41
+# Install binaries
42
+log_info "Installing binaries to /usr/bin..."
43
+install -Dm755 target/release/gardmd /usr/bin/gardmd
44
+install -Dm755 target/release/gardm-greeter /usr/bin/gardm-greeter
45
+
46
+# Create config directories
47
+log_info "Creating configuration directories..."
48
+mkdir -p /etc/gardm
49
+mkdir -p /usr/share/gardm/backgrounds
50
+
51
+# Install PAM configuration
52
+log_info "Installing PAM configuration..."
53
+install -Dm644 etc/pam.d/gardm /etc/pam.d/gardm
54
+
55
+# Install systemd service
56
+log_info "Installing systemd service..."
57
+install -Dm644 etc/gardm.service /usr/lib/systemd/system/gardm.service
58
+
59
+# Install default config if not exists
60
+if [ ! -f /etc/gardm/config.toml ]; then
61
+    log_info "Installing default configuration..."
62
+    install -Dm644 etc/config.toml /etc/gardm/config.toml
63
+else
64
+    log_warn "/etc/gardm/config.toml already exists, not overwriting"
65
+fi
66
+
67
+# Create sysconfig file (empty, for environment overrides)
68
+if [ ! -f /etc/sysconfig/gardm ]; then
69
+    echo "# Environment variables for gardm" > /etc/sysconfig/gardm
70
+    chmod 644 /etc/sysconfig/gardm
71
+fi
72
+
73
+# Reload systemd
74
+log_info "Reloading systemd daemon..."
75
+systemctl daemon-reload
76
+
77
+log_info "Installation complete!"
78
+echo ""
79
+echo "To enable gardm as your display manager:"
80
+echo "  1. First, TEST gardm (see scripts/test-gardm.sh)"
81
+echo "  2. Then disable your current display manager:"
82
+echo "     sudo systemctl disable sddm  # or gdm, lightdm, etc."
83
+echo "  3. Enable gardm:"
84
+echo "     sudo systemctl enable gardm"
85
+echo "  4. Reboot"
86
+echo ""
87
+log_warn "ALWAYS keep a terminal/tty login available as fallback!"
scripts/swap-dm.shadded
@@ -0,0 +1,173 @@
1
+#!/bin/bash
2
+# Safely swap display managers (e.g., SDDM -> gardm)
3
+# This script includes safety checks and rollback instructions
4
+
5
+set -e
6
+
7
+RED='\033[0;31m'
8
+GREEN='\033[0;32m'
9
+YELLOW='\033[1;33m'
10
+BLUE='\033[0;34m'
11
+NC='\033[0m'
12
+
13
+log_info() {
14
+    echo -e "${GREEN}[INFO]${NC} $1"
15
+}
16
+
17
+log_warn() {
18
+    echo -e "${YELLOW}[WARN]${NC} $1"
19
+}
20
+
21
+log_error() {
22
+    echo -e "${RED}[ERROR]${NC} $1"
23
+}
24
+
25
+log_step() {
26
+    echo -e "${BLUE}[STEP]${NC} $1"
27
+}
28
+
29
+if [ "$EUID" -ne 0 ]; then
30
+    log_error "Please run as root (sudo ./swap-dm.sh)"
31
+    exit 1
32
+fi
33
+
34
+echo "============================================"
35
+echo "  gardm Display Manager Swap Utility"
36
+echo "============================================"
37
+echo ""
38
+
39
+# Detect current display manager
40
+CURRENT_DM=""
41
+for dm in sddm gdm gdm3 lightdm lxdm; do
42
+    if systemctl is-enabled "$dm" >/dev/null 2>&1; then
43
+        CURRENT_DM="$dm"
44
+        break
45
+    fi
46
+done
47
+
48
+if [ -z "$CURRENT_DM" ]; then
49
+    log_warn "Could not detect current display manager"
50
+    echo "Which display manager are you currently using?"
51
+    echo "  1) sddm"
52
+    echo "  2) gdm"
53
+    echo "  3) lightdm"
54
+    echo "  4) other"
55
+    read -p "Selection [1-4]: " choice
56
+    case $choice in
57
+        1) CURRENT_DM="sddm" ;;
58
+        2) CURRENT_DM="gdm" ;;
59
+        3) CURRENT_DM="lightdm" ;;
60
+        *)
61
+            read -p "Enter the service name: " CURRENT_DM
62
+            ;;
63
+    esac
64
+fi
65
+
66
+log_info "Detected current display manager: $CURRENT_DM"
67
+echo ""
68
+
69
+# Pre-flight checks
70
+log_step "Running pre-flight checks..."
71
+
72
+# Check gardm is installed
73
+if [ ! -x /usr/bin/gardmd ]; then
74
+    log_error "gardmd not found at /usr/bin/gardmd"
75
+    log_error "Please run install.sh first"
76
+    exit 1
77
+fi
78
+
79
+if [ ! -x /usr/bin/gardm-greeter ]; then
80
+    log_error "gardm-greeter not found at /usr/bin/gardm-greeter"
81
+    log_error "Please run install.sh first"
82
+    exit 1
83
+fi
84
+
85
+# Check systemd service exists
86
+if [ ! -f /usr/lib/systemd/system/gardm.service ]; then
87
+    log_error "gardm.service not found"
88
+    log_error "Please run install.sh first"
89
+    exit 1
90
+fi
91
+
92
+# Check PAM config
93
+if [ ! -f /etc/pam.d/gardm ]; then
94
+    log_error "PAM configuration not found at /etc/pam.d/gardm"
95
+    log_error "Please run install.sh first"
96
+    exit 1
97
+fi
98
+
99
+log_info "All pre-flight checks passed"
100
+echo ""
101
+
102
+# Safety warnings
103
+echo "============================================"
104
+echo "  IMPORTANT SAFETY INFORMATION"
105
+echo "============================================"
106
+echo ""
107
+log_warn "Swapping display managers can prevent graphical login!"
108
+echo ""
109
+echo "BEFORE PROCEEDING, ensure you can:"
110
+echo "  1. Switch to a TTY (Ctrl+Alt+F2 through F6)"
111
+echo "  2. Log in via TTY as your user"
112
+echo "  3. Have root/sudo access from TTY"
113
+echo ""
114
+echo "ROLLBACK PROCEDURE (if gardm fails):"
115
+echo "  1. Switch to TTY: Ctrl+Alt+F2"
116
+echo "  2. Log in as your user"
117
+echo "  3. Run: sudo systemctl disable gardm"
118
+echo "  4. Run: sudo systemctl enable $CURRENT_DM"
119
+echo "  5. Reboot: sudo reboot"
120
+echo ""
121
+
122
+read -p "Have you tested gardm with test-gardm.sh? [y/N]: " tested
123
+if [ "$tested" != "y" ] && [ "$tested" != "Y" ]; then
124
+    log_warn "It's recommended to test gardm first!"
125
+    log_warn "Run: sudo ./test-gardm.sh"
126
+    echo ""
127
+    read -p "Continue anyway? [y/N]: " continue
128
+    if [ "$continue" != "y" ] && [ "$continue" != "Y" ]; then
129
+        log_info "Aborted. Please test gardm first."
130
+        exit 0
131
+    fi
132
+fi
133
+
134
+echo ""
135
+read -p "Ready to swap $CURRENT_DM -> gardm? [y/N]: " confirm
136
+if [ "$confirm" != "y" ] && [ "$confirm" != "Y" ]; then
137
+    log_info "Aborted by user"
138
+    exit 0
139
+fi
140
+
141
+echo ""
142
+log_step "Disabling $CURRENT_DM..."
143
+systemctl disable "$CURRENT_DM"
144
+
145
+log_step "Enabling gardm..."
146
+systemctl enable gardm
147
+
148
+echo ""
149
+log_info "Display manager swap complete!"
150
+echo ""
151
+echo "============================================"
152
+echo "  NEXT STEPS"
153
+echo "============================================"
154
+echo ""
155
+echo "1. Reboot your system: sudo reboot"
156
+echo "2. gardm should start instead of $CURRENT_DM"
157
+echo ""
158
+echo "If gardm fails to start:"
159
+echo "  - Switch to TTY (Ctrl+Alt+F2)"
160
+echo "  - Run: sudo systemctl disable gardm"
161
+echo "  - Run: sudo systemctl enable $CURRENT_DM"
162
+echo "  - Run: sudo reboot"
163
+echo ""
164
+echo "To check gardm status after reboot:"
165
+echo "  systemctl status gardm"
166
+echo "  journalctl -u gardm -b"
167
+echo ""
168
+
169
+read -p "Reboot now? [y/N]: " reboot_now
170
+if [ "$reboot_now" = "y" ] || [ "$reboot_now" = "Y" ]; then
171
+    log_info "Rebooting..."
172
+    reboot
173
+fi
scripts/test-gardm.shadded
@@ -0,0 +1,87 @@
1
+#!/bin/bash
2
+# Test gardm without replacing your current display manager
3
+# This script runs gardm on a different VT/display for testing
4
+
5
+set -e
6
+
7
+RED='\033[0;31m'
8
+GREEN='\033[0;32m'
9
+YELLOW='\033[1;33m'
10
+NC='\033[0m'
11
+
12
+log_info() {
13
+    echo -e "${GREEN}[INFO]${NC} $1"
14
+}
15
+
16
+log_warn() {
17
+    echo -e "${YELLOW}[WARN]${NC} $1"
18
+}
19
+
20
+log_error() {
21
+    echo -e "${RED}[ERROR]${NC} $1"
22
+}
23
+
24
+# Check if running as root
25
+if [ "$EUID" -ne 0 ]; then
26
+    log_error "Please run as root (sudo ./test-gardm.sh)"
27
+    exit 1
28
+fi
29
+
30
+# Find an unused display
31
+find_unused_display() {
32
+    for i in {1..9}; do
33
+        if [ ! -e "/tmp/.X$i-lock" ] && [ ! -S "/tmp/.X11-unix/X$i" ]; then
34
+            echo ":$i"
35
+            return
36
+        fi
37
+    done
38
+    echo ":99"
39
+}
40
+
41
+# Find an unused VT (above the typical user range)
42
+find_unused_vt() {
43
+    for vt in {7..12}; do
44
+        if ! fuser "/dev/tty$vt" >/dev/null 2>&1; then
45
+            echo "$vt"
46
+            return
47
+        fi
48
+    done
49
+    echo "8"
50
+}
51
+
52
+DISPLAY_NUM=$(find_unused_display)
53
+VT_NUM=$(find_unused_vt)
54
+
55
+log_info "Testing gardm on display $DISPLAY_NUM, VT $VT_NUM"
56
+log_warn "Press Ctrl+C here (or switch back to your main VT) to stop the test"
57
+echo ""
58
+echo "To switch VTs:"
59
+echo "  - Ctrl+Alt+F1 through F7 (or F2-F8 depending on your setup)"
60
+echo "  - Your current session is likely on VT 1 or 2"
61
+echo ""
62
+echo "Press Enter to start test, or Ctrl+C to cancel..."
63
+read
64
+
65
+# Check if binaries exist
66
+if [ ! -x /usr/bin/gardmd ]; then
67
+    log_error "gardmd not installed. Run install.sh first."
68
+    exit 1
69
+fi
70
+
71
+if [ ! -x /usr/bin/gardm-greeter ]; then
72
+    log_error "gardm-greeter not installed. Run install.sh first."
73
+    exit 1
74
+fi
75
+
76
+# Check PAM config
77
+if [ ! -f /etc/pam.d/gardm ]; then
78
+    log_error "PAM config not installed. Run install.sh first."
79
+    exit 1
80
+fi
81
+
82
+log_info "Starting gardmd on display $DISPLAY_NUM, VT $VT_NUM..."
83
+log_info "You will be switched to VT $VT_NUM"
84
+
85
+# Run gardmd directly (not via systemd, for testing)
86
+# The daemon will start X on the specified display/VT
87
+exec /usr/bin/gardmd --display "$DISPLAY_NUM" --vt "$VT_NUM"