44ceea7 ยท 1 month ago 7 commits
  1#include <stdbool.h>
  2#include <stdlib.h>
  3#include <sys/types.h>
  4#include <unistd.h>
  5#include "comm.h"
  6#include "log.h"
  7#include "swaylock.h"
  8#include "password-buffer.h"
  9
 10static int comm[2][2] = {{-1, -1}, {-1, -1}};
 11
 12ssize_t read_comm_request(char **buf_ptr) {
 13	size_t size;
 14	ssize_t amt;
 15	amt = read(comm[0][0], &size, sizeof(size));
 16	if (amt == 0) {
 17		return 0;
 18	} else if (amt < 0) {
 19		swaylock_log_errno(LOG_ERROR, "read pw request");
 20		return -1;
 21	}
 22	swaylock_log(LOG_DEBUG, "received pw check request");
 23	char *buf = password_buffer_create(size);
 24	if (!buf) {
 25		return -1;
 26	}
 27	size_t offs = 0;
 28	do {
 29		amt = read(comm[0][0], &buf[offs], size - offs);
 30		if (amt <= 0) {
 31			swaylock_log_errno(LOG_ERROR, "failed to read pw");
 32			return -1;
 33		}
 34		offs += (size_t)amt;
 35	} while (offs < size);
 36
 37	*buf_ptr = buf;
 38	return size;
 39}
 40
 41bool write_comm_reply(bool success) {
 42	if (write(comm[1][1], &success, sizeof(success)) != sizeof(success)) {
 43		swaylock_log_errno(LOG_ERROR, "failed to write pw check result");
 44		return false;
 45	}
 46	return true;
 47}
 48
 49bool spawn_comm_child(void) {
 50	if (pipe(comm[0]) != 0) {
 51		swaylock_log_errno(LOG_ERROR, "failed to create pipe");
 52		return false;
 53	}
 54	if (pipe(comm[1]) != 0) {
 55		swaylock_log_errno(LOG_ERROR, "failed to create pipe");
 56		return false;
 57	}
 58	pid_t child = fork();
 59	if (child < 0) {
 60		swaylock_log_errno(LOG_ERROR, "failed to fork");
 61		return false;
 62	} else if (child == 0) {
 63		close(comm[0][1]);
 64		close(comm[1][0]);
 65		run_pw_backend_child();
 66	}
 67	close(comm[0][0]);
 68	close(comm[1][1]);
 69	return true;
 70}
 71
 72bool write_comm_request(struct swaylock_password *pw) {
 73	bool result = false;
 74
 75	size_t len = pw->len + 1;
 76	size_t offs = 0;
 77	if (write(comm[0][1], &len, sizeof(len)) < 0) {
 78		swaylock_log_errno(LOG_ERROR, "Failed to request pw check");
 79		goto out;
 80	}
 81
 82	do {
 83		ssize_t amt = write(comm[0][1], &pw->buffer[offs], len - offs);
 84		if (amt < 0) {
 85			swaylock_log_errno(LOG_ERROR, "Failed to write pw buffer");
 86			goto out;
 87		}
 88		offs += amt;
 89	} while (offs < len);
 90
 91	result = true;
 92
 93out:
 94	clear_password_buffer(pw);
 95	return result;
 96}
 97
 98bool read_comm_reply(void) {
 99	bool result = false;
100	if (read(comm[1][0], &result, sizeof(result)) != sizeof(result)) {
101		swaylock_log_errno(LOG_ERROR, "Failed to read pw result");
102		result = false;
103	}
104	return result;
105}
106
107int get_comm_reply_fd(void) {
108	return comm[1][0];
109}