Minishell for accessing txtinfo through sshd/dropbear
authorHenning Rogge <rogge@fgan.de>
Mon, 27 Apr 2009 11:38:45 +0000 (13:38 +0200)
committerHenning Rogge <rogge@fgan.de>
Mon, 27 Apr 2009 11:38:45 +0000 (13:38 +0200)
Makefile
contrib/txtinfoshell/Makefile [new file with mode: 0644]
contrib/txtinfoshell/README [new file with mode: 0644]
contrib/txtinfoshell/txtinfoshell.c [new file with mode: 0644]

index d36c55b..1795326 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -231,7 +231,10 @@ watchdog:
                $(MAKECMD) -C lib/watchdog
                $(MAKECMD) -C lib/watchdog DESTDIR=$(DESTDIR) install
 
-build_all:     all libs config-verify
+txtinfoshell:
+       $(MAKECMD) -C contrib/txtinfoshell
+
+build_all:     all libs txtinfoshell config-verify
 install_all:   install install_libs config-verify_install
 clean_all:     clean clean_libs config-verify_clean
 
diff --git a/contrib/txtinfoshell/Makefile b/contrib/txtinfoshell/Makefile
new file mode 100644 (file)
index 0000000..d25b5df
--- /dev/null
@@ -0,0 +1,19 @@
+SRC += $(wildcard ./*.c)
+
+OBJS = $(SRC:.c=.o)
+
+CC = gcc
+CFLAGS = -c -g0 -Os -Wall -Werror
+LFLAGS = -Wall
+
+.c.o:
+       ${CC} ${CFLAGS} -o $@ $^
+
+all: txtinfo-sh
+
+txtinfo-sh:    ${OBJS}
+       ${CC} -o ./$@ ${LFLAGS} ${OBJS}
+
+clean:
+       rm -f ${OBJS} ./txtinfo-sh
+
diff --git a/contrib/txtinfoshell/README b/contrib/txtinfoshell/README
new file mode 100644 (file)
index 0000000..277aa37
--- /dev/null
@@ -0,0 +1,12 @@
+   txtinfo shell
+===================
+
+txtinfo-sh is a small helper programm to allow external users a secure
+access to the txtinfo plugin. It can be used as a shell for an user
+in /etc/passwd and connects the incoming ssh session directly to port 2006
+of the olsrd txtinfo plugin. The txtinfo itself have to be configured to
+allow access by 127.0.0.1.
+
+If txtinfo is running on another port change the DEFAULT_TXTINFO_PORT
+constant in txtinfoshell.c or use a shell script as a wrapper that
+starts txtinfo-sh with the port number as the only parameter.
diff --git a/contrib/txtinfoshell/txtinfoshell.c b/contrib/txtinfoshell/txtinfoshell.c
new file mode 100644 (file)
index 0000000..dff0af0
--- /dev/null
@@ -0,0 +1,148 @@
+/*
+ * txtinfoshell.c
+ *
+ *  Created on: 27.04.2009
+ *      Author: rogge
+ */
+
+/*
+ ** client.c -- a stream socket client demo
+ */
+
+#include <errno.h>
+#include <signal.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <arpa/inet.h>
+#include <sys/socket.h>
+
+#define DEFAULT_TXTINFO_PORT 2006
+#define BLOCKSIZE 2048
+
+int running;
+
+/*
+ * signalHandler
+ *
+ * This handler stops the mainloop when the programm is send a signal
+ * to stop
+ */
+static void
+signalHandler(int signo __attribute__ ((unused)))
+{
+  running = 0;
+}
+
+int
+main(int argc, char *argv[]) {
+  int sockfd;
+  char buf[BLOCKSIZE];
+  struct sockaddr_in localSocket;
+  fd_set readSet;
+  int port = DEFAULT_TXTINFO_PORT;
+
+  /* parse parameter */
+  switch (argc) {
+    case 1:
+      break;
+    case 2:
+      if ((strcmp(argv[1], "-h") != 0) && (strcmp(argv[1], "--help") != 0)) {
+        port = atoi(argv[1]);
+        break;
+      }
+    default:
+      fprintf(stderr, "Usage: txtinfo-sh [port]\n");
+      return 0;
+  }
+
+  memset(&localSocket, 0, sizeof(localSocket));
+  localSocket.sin_family = AF_INET;
+  localSocket.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
+  localSocket.sin_port = htons(port);
+
+  if ((sockfd = socket(PF_INET, SOCK_STREAM, 0)) == -1) {
+    perror("Cannot open socket to connect to olsrd");
+    return 0;
+  }
+
+  if (connect(sockfd, (struct sockaddr *)&localSocket, sizeof(localSocket)) == -1) {
+    close(sockfd);
+    perror("Cannot connect to olsrd");
+    return 0;
+  }
+
+  running = 1;
+
+  /* activate signal handling */
+  signal(SIGABRT, &signalHandler);
+  signal(SIGTERM, &signalHandler);
+  signal(SIGQUIT, &signalHandler);
+  signal(SIGINT, &signalHandler);
+
+  while (running) {
+    int result;
+    struct timeval tv;
+
+    FD_ZERO(&readSet);
+
+    FD_SET(STDIN_FILENO, &readSet);
+    FD_SET(sockfd, &readSet);
+
+    tv.tv_sec = 1;
+    tv.tv_usec = 0;
+
+    result = select(sockfd+1, &readSet, NULL, NULL, &tv);
+    if (result < 0) {
+      perror("select");
+      break;
+    }
+
+    if (result > 0) {
+      if (FD_ISSET(STDIN_FILENO, &readSet)) {
+        /* stdin/out need read/write */
+        ssize_t len = 0;
+        ssize_t s = 0;
+
+        len = read(STDIN_FILENO, buf, sizeof(buf));
+
+        while (s < len) {
+          /* sockets use recv/send */
+          ssize_t w = send(sockfd, &buf[s], len - s, 0);
+          if (w <= 0) {
+            running = 0;
+            perror("socket-send");
+            break;
+          }
+          s += w;
+        }
+      }
+      if (FD_ISSET(sockfd, &readSet)) {
+        /* sockets use recv/send */
+        ssize_t len = 0;
+        ssize_t s = 0;
+
+        len = recv(sockfd, buf, sizeof(buf), 0);
+        if (len == 0) {
+          // socket closed
+          running = 0;
+          break;
+        }
+
+        while (s < len) {
+          /* stdin/out need read/write */
+          ssize_t w = write(STDOUT_FILENO, &buf[s], len - s);
+          if (w <= 0) {
+            running = 0;
+            perror("stdout-send");
+            break;
+          }
+          s += w;
+        }
+      }
+    }
+  }
+  close(sockfd);
+  return 0;
+}