sysrqd-14/0000755002342400017510000000000011405402742011434 5ustar jdanjoueesysrqd-14/Makefile0000644002342400017510000000161211304703040013065 0ustar jdanjoueeVERSION=$(shell grep '^Version' ChangeLog | head -n 1 | cut -d' ' -f2 | tr -d ' ') BIN=sysrqd O=sysrqd.o CFLAGS+=-W -Wall -Wextra \ -Wundef -Wshadow -Wcast-align -Wwrite-strings -Wsign-compare \ -Wunused -Winit-self -Wpointer-arith -Wredundant-decls \ -Wmissing-prototypes -Wmissing-format-attribute -Wmissing-noreturn \ -std=gnu99 -pipe -DSYSRQD_VERSION="\"$(VERSION)\"" -O3 SBINDIR=$(DESTDIR)/usr/sbin #MANDIR=$(DESTDIR)/usr/share/man/man1 INSTALL = install #MAN=sysrqd.1 $(BIN): $(O) $(CC) $(LDFLAGS) -o $(BIN) $(O) install: $(BIN) $(INSTALL) -d -m 755 $(SBINDIR) $(INSTALL) -m 755 $(BIN) $(SBINDIR) #$(INSTALL) -d -m 755 $(MANDIR) #$(INSTALL) -m 644 $(MAN) $(MANDIR) clean: rm -f *~ $(O) $(BIN) release: clean mkdir ../$(BIN)-$(VERSION) cp -a * ../$(BIN)-$(VERSION) cd .. && tar czf $(BIN)-$(VERSION).tar.gz $(BIN)-$(VERSION) rm -rf ../$(BIN)-$(VERSION) sysrqd-14/AUTHORS0000644002342400017510000000004311144775217012513 0ustar jdanjoueeJulien Danjou sysrqd-14/README0000644002342400017510000000115211144775217012325 0ustar jdanjouee _ ___ _ _ ___ _ __ __ _ __| | / __| | | / __| '__/ _` |/ _` | \__ \ |_| \__ \ | | (_| | (_| | |___/\__, |___/_| \__, |\__,_| |___/ |_| « Don't let me down. » -- The Beatles sysrqd is a small daemon intended to manage Linux SysRq over network. Its philosophy is to be very responsive under heavy load and try to be somehow reliable. Authentication is made by clear password. Connection should be made to port 4094. *** WARNING *** Please, be careful if you use 'e' (tErm) and 'i' (kIll). This will kill all processes, including sysrqd! sysrqd-14/sysrqd.c0000644002342400017510000001523211405402613013125 0ustar jdanjouee/* * sysrqd.c - Daemon to control sysrq over network * * © 2005-2009 Julien Danjou * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; version 2 dated June, 1991. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #define PASS_MAX_LEN 32 #define BIND_MAX_LEN 16 #define PROMPT "sysrq> " #define SYSRQ_TRIGGER_PATH "/proc/sysrq-trigger" #define AUTH_FILE "/etc/sysrqd.secret" #define BINDIP_FILE "/etc/sysrqd.bind" #define PID_FILE "/var/run/sysrqd.pid" #define SYSRQD_PRIO -19 #define SYSRQD_LISTEN_PORT 4094 char pwd[PASS_MAX_LEN]; int sock_serv; /* Macro used to write a string to the client */ #define write_cli(s) \ write(sock_client, s, sizeof(s) - 1); /* Macro used to write the prompt */ #define write_prompt(s) \ write_cli(PROMPT); #define errmsg(s) \ fprintf(stderr, "%s (%s:%d)\n", s, __FILE__, __LINE__); /* Authenticate the connection */ static int auth (int sock_client) { char buf[PASS_MAX_LEN]; size_t len; write_cli("sysrqd password: "); memset(buf, 0, sizeof(buf)); /* Read password */ len = read(sock_client, buf, sizeof(buf) - 1); /* remove \r and \n at end */ while(len > 0 && (buf[len - 1] == '\n' || buf[len - 1] == '\r')) len--; /* If password has been sent */ if(len > 0) { buf[len] = '\0'; if(!strcmp(buf, pwd)) return 1; else write_cli("Go away!\r\n"); } return 0; } /* Read a configuration file */ static int read_conffile (const char *file, char* buf, size_t buflen) { int fd; if((fd = open (file, O_RDONLY)) == -1) { syslog(LOG_ERR, "Unable to open file %s: %s", file, strerror(errno)); return 1; } memset(buf, 0, buflen); read (fd, buf, buflen - 1); close (fd); buf[buflen - 1] = '\0'; /* Strip last \n */ char *tmp; if((tmp = strchr(buf, '\n'))) *tmp = '\0'; return 0; } /* Read commands */ static void read_cmd (int sock_client, int fd_sysrq) { char buf = 0; write_prompt(); do { if(buf == '\n') write_prompt(); if((buf >= 48 && buf <= 57) || (buf >= 97 && buf <= 122 )) write(fd_sysrq, &buf, 1); } while(read (sock_client, &buf, 1) == 1 && buf != 'q'); } /* * Listen to a port, * authenticate connection * and execute commands */ static int start_listen (int fd_sysrq) { int sock_client; socklen_t size_addr; struct sockaddr_in addr; struct sockaddr_in addr_client; int opt; char bindip[BIND_MAX_LEN]; addr.sin_family = AF_INET; addr.sin_port = htons(SYSRQD_LISTEN_PORT); if(read_conffile(BINDIP_FILE, bindip, sizeof(bindip))) addr.sin_addr.s_addr = INADDR_ANY; else if(inet_aton(bindip, &addr.sin_addr)) { syslog(LOG_ERR, "Unable to convert IP: %s, using INADDR_ANY", strerror(errno)); addr.sin_addr.s_addr = INADDR_ANY; } if(!(sock_serv = socket (PF_INET, SOCK_STREAM, 0))) { syslog(LOG_ERR, "Error while creating server socket: %s", strerror(errno)); return 1; } /* We tries to avoid "socket already in use" errors */ opt = 1; setsockopt(sock_serv, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof (opt)); if(bind (sock_serv, (struct sockaddr *) &addr, sizeof (addr))) { syslog(LOG_ERR, "Unable to bind(): %s", strerror(errno)); return 1; } if(listen(sock_serv, 2)) { syslog(LOG_ERR, "Unable to listen(): %s", strerror(errno)); return 1; } size_addr = sizeof (addr_client); syslog(LOG_INFO, "Listening on port tcp/%d", SYSRQD_LISTEN_PORT); while((sock_client = accept (sock_serv, (struct sockaddr *) &addr_client, &size_addr))) { if(auth (sock_client)) read_cmd (sock_client, fd_sysrq); close(sock_client); } close (sock_serv); return 0; } static void __attribute__ ((noreturn)) signal_handler (void) { close (sock_serv); exit (EXIT_FAILURE); } static int catch_signals (void) { struct sigaction sa; sigset_t mask; sigfillset (&mask); sa.sa_handler = (void *) &signal_handler; sa.sa_mask = mask; sigaction (SIGINT, &sa, NULL); sigaction (SIGTERM, &sa, NULL); /* ignore sigpipe */ sigemptyset(&mask); sigaddset(&mask, SIGPIPE); sigprocmask(SIG_BLOCK, &mask, NULL); return 0; } static int write_pidfile(pid_t pid) { FILE *pidf = fopen(PID_FILE, "w"); if (pidf == NULL) return 1; fprintf(pidf, "%d\n", pid); fclose(pidf); return 0; } static void do_on_exit(void) { syslog(LOG_NOTICE, "Exiting"); } int main (void) { int fd_sysrq; atexit(do_on_exit); /* We test if it is worth the pain to fork if setpriority would fail */ if(getuid() != 0) { errmsg ("Only root can run this program."); return 1; } /* We read our password */ if(read_conffile (AUTH_FILE, pwd, sizeof(pwd))) return EXIT_FAILURE; /* mlock, we want this to always run */ mlockall(MCL_CURRENT | MCL_FUTURE); /* We daemonize */ daemon(0, 0); openlog ("sysrqd", LOG_PID, LOG_DAEMON); syslog(LOG_PID | LOG_DAEMON, "Starting"); if(write_pidfile(getpid())) syslog (LOG_PID | LOG_DAEMON, "Unable to write pidfile"); /* We set our priority */ if(setpriority (PRIO_PROCESS, 0, SYSRQD_PRIO)) { syslog (LOG_PID | LOG_DAEMON, "Unable to set priority: %s", strerror(errno)); return EXIT_FAILURE; } /* Catch some signals */ catch_signals (); /* We keep the sysrq-trigger file opened */ fd_sysrq = open(SYSRQ_TRIGGER_PATH, O_SYNC|O_WRONLY); if(fd_sysrq == -1) { syslog(LOG_ERR, "Error while opening sysrq trigger: %s", strerror(errno)); return EXIT_FAILURE; } /* Now listen */ if(!start_listen (fd_sysrq)) return EXIT_FAILURE; /* If we quit, close the trigger */ close (fd_sysrq); closelog(); return EXIT_SUCCESS; } sysrqd-14/INSTALL0000644002342400017510000000100511144775217012473 0ustar jdanjoueeSymple type: % make % make install - Read the README file. - Create a password file: echo "mypassword" > /etc/sysrqd.secret chmod 0600 /etc/sysrqd.secret - Optionnaly, create a bind file to bind to a specific IP echo 192.168.2.13 > /etc/sysrqd.bind - Add it to your local daemons startup. If you need to tweak some paramaters, take a look on define at the beginning of sysrqd.c You can add this lines to /etc/services: sysrqd 4094/tcp # sysrq daemon sysrqd 4094/udp # sysrq daemon sysrqd-14/ChangeLog0000644002342400017510000000330111405402715013203 0ustar jdanjoueeVersion 14 -- Tue, 16 Mar 2010 16:54:22 +0100 * Fix authentification with clients not sending \r\n Version 13 -- Mon, 30 Nov 2009 09:51:24 +0100 * No code change, but version 12 was badly released with no changelog and bad tarball. Version 12 -- Mon, 19 Oct 2009 14:03:01 +0200 * Ignore SIGPIPE Version 11 -- Mon, 19 Oct 2009 11:30:52 +0200 * Do not try to write anything if read() has failed while reading password. Fix a crash using e.g. nmap. Version 10 -- Thu, 12 Feb 2009 12:05:54 +0100 * memset() our pwd/bindip * Merge read password and bindfile functions * Add more things to syslog * Fix authentification Version 9 -- Fri, 19 Jan 2007 15:32:00 +0100 * Add a warning about TERM and KILL in README * Merge a patch from Neil McGovern: - don't go in swap, always stay in memory - if /etc/sysrqd.bind exists, bind to a specific ip instead of any. Version 8 -- Tue, 11 Jul 2006 11:41:05 +0200 * Use official ports registered by IANA: sysrqd 4094/tcp sysrq daemon sysrqd 4094/udp sysrq daemon Version 7 -- Tue, 16 May 2006 15:55:55 +0200 * Call daemon() instead of simply forking Version 6 -- Tue, 16 May 2006 15:00:44 +0200 * Fix bug with pid file (Thanks to Norbert Kiesel ) * Change default port to 880 Version 5 -- Mon, 1 May 2006 11:58:21 +0200 * Fix little bug with open() Version 4 -- Sun, 30 Apr 2006 21:50:51 +0200 * Add support of syslog * Fork and run in background * Write a pid file Version 3 -- Sat, 11 Mar 2006 11:48:00 +0100 * Fix little bug if password file does not have \n Version 2 -- Mon, 29 Aug 2005 17:06:00 +0200 * Remove init.d script Version 1 -- Mon, 29 Aug 2005 11:02:26 +0200 * Initial release