rsudo/rsudo.c

174 lines
3.9 KiB
C

/*
rsudo - request sudo
this file and distributions are
memework property.
unauthorized distribution of this file
and related files (like header files)
is strictly prohibited by people other than the owner.
Copyright (C) Luna Mendes 2017 - 2018
*/
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <sys/stat.h>
#include <sys/un.h>
#include <unistd.h>
#include "log.h"
// lol C bool lib
typedef int bool;
enum { false, true };
const char *sock_path = "/var/sock/memed.sock";
struct args_context {
int positional_count;
char **positional;
bool nowait;
};
struct header_s {
unsigned int len;
int op;
};
char *join(char *s1, char *s2) {
char *result = malloc(strlen(s1) + strlen(s2) + 1);
if (result) {
strcpy(result, s1);
strcat(result, s2);
}
return result;
}
void print_help() {
printf("sudo thing that integrates (badly) with discord\n\n"
"made by: luba and arsen\n\n"
"Usage: <--nowait> [command ...]\n"
" --nowait - Schedule command for execution by memed\n");
}
int main(int argc, char **argv) {
if (argc == 1) {
print_help();
return -1;
}
// the idea here is to open the socket
// send a message to it and run asap
struct sockaddr_un addr;
// receiving data from socket
struct header_s header;
char buffer[1024];
// fd file descriptor
// rc read count
int fd, rc;
if ((fd = socket(AF_UNIX, SOCK_STREAM, 0)) == -1) {
perror("socket error");
exit(-1);
}
memset(&addr, 0, sizeof(addr));
addr.sun_family = AF_UNIX;
strncpy(addr.sun_path, sock_path, sizeof(addr.sun_path) - 1);
LOG_INFO("main", "connecting");
if (connect(fd, (struct sockaddr *)&addr, sizeof(addr)) == -1) {
perror("connect error");
exit(-1);
}
// read the hello
// We start by reading and filling our header
if ((rc = recv(fd, &header, 8, 0)) < 0) {
perror("recv");
exit(-1);
}
if (strcmp(argv[1], "--nowait") == 0) {
argv++; // luba pls no use argv[0] becus its --nowait now
printf("%d %d\n", header.len, header.op);
// Then we proceed to, with the data from header,
// read the message
if ((rc = recv(fd, &buffer, header.len, 0)) < 0) {
perror("recv");
exit(-1);
}
if (header.op != 0) {
LOG_ERROR("main", "incorrect header op");
exit(-1);
}
LOG_INFO("main", "finished hello");
char *tot = malloc(1);
*tot = 0;
for (int i = 1; i < argc - 1; i++) {
char *arg = argv[i];
tot = join(tot, arg);
if (i != argc - 1) tot = join(tot, " ");
}
// convert uid to string
int uid = getuid();
char uid_str[6];
sprintf(uid_str, "%d", uid);
tot = join(tot, ",");
tot = join(tot, uid_str);
tot = join(tot, ",");
tot = join(tot, getenv("USER"));
printf("sending command: %s\n", tot);
// encode our data
struct header_s send_h;
send_h.len = strlen(tot);
send_h.op = 2;
if (send(fd, &send_h, sizeof(send_h), 0) < 0) {
perror("send req");
exit(-1);
}
if (send(fd, tot, strlen(tot), 0) < 0) {
perror("send req total");
exit(-1);
}
shutdown(fd, SHUT_RDWR);
printf("Successfully communicated your command to memed!\n");
close(fd);
exit(0);
} else {
// TODO luna make thje check
setuid(0);
setenv("USER", "root", true);
setenv("HOME", "/root", true); // todo: dont care
int err = execvp(argv[1], argv + 1);
if (err == -1)
perror("rsudo: exec");
else
return err;
}
}