summarylogtreecommitdiffstats
diff options
context:
space:
mode:
authorElmar Klausmeier2022-11-01 13:39:17 +0100
committerElmar Klausmeier2022-11-01 13:39:17 +0100
commitb088cfc6232e64b3e0b6c9739865d60cb2282da6 (patch)
treed25b244fcceae2476a6dc93a1ba6969994207e0c
downloadaur-ttyd-addon.tar.gz
Initial revision
-rw-r--r--.SRCINFO17
-rw-r--r--PKGBUILD27
-rw-r--r--slogin.c174
-rw-r--r--ttyd.service18
4 files changed, 236 insertions, 0 deletions
diff --git a/.SRCINFO b/.SRCINFO
new file mode 100644
index 000000000000..82e066e45e20
--- /dev/null
+++ b/.SRCINFO
@@ -0,0 +1,17 @@
+pkgbase = ttyd-addon
+ pkgdesc = Addons for ttyd, which provides sharing your terminal over the web
+ pkgver = 1.0.0
+ pkgrel = 1
+ arch = i686
+ arch = x86_64
+ arch = armv6h
+ arch = armv7h
+ arch = aarch64
+ license = MIT
+ depends = ttyd
+ source = ttyd.service
+ source = https://raw.githubusercontent.com/eklausme/c/master/slogin.c
+ sha512sums = e265ed981d1a2a4a49005864aa7f7d88dc03455375434ce557daf9bb928401aaeab553bce1f5ef2116490c0d7ff78377163a601e78ebabcc5750cbf845489710
+ sha512sums = 1cebf87e06f6303c48d931a87614f05d7300b4fba45ac5bf5a56ac20a0c9f48a1997bce13611ab3b498eed991a74594318c49ae801595fc882755dc1928640bb
+
+pkgname = ttyd-addon
diff --git a/PKGBUILD b/PKGBUILD
new file mode 100644
index 000000000000..479ef50e5ee0
--- /dev/null
+++ b/PKGBUILD
@@ -0,0 +1,27 @@
+# Submitter: Elmar Klausmeier <Elmar.Klausmeier@gmail.com>
+
+pkgname=ttyd-addon
+pkgver=1.0.0
+pkgrel=1
+pkgdesc='Addons for ttyd, which provides sharing your terminal over the web'
+arch=('i686' 'x86_64' 'armv6h' 'armv7h' 'aarch64')
+license=('MIT')
+depends=('ttyd')
+source=("ttyd.service"
+ "https://raw.githubusercontent.com/eklausme/c/master/slogin.c")
+sha512sums=('e265ed981d1a2a4a49005864aa7f7d88dc03455375434ce557daf9bb928401aaeab553bce1f5ef2116490c0d7ff78377163a601e78ebabcc5750cbf845489710'
+ '1cebf87e06f6303c48d931a87614f05d7300b4fba45ac5bf5a56ac20a0c9f48a1997bce13611ab3b498eed991a74594318c49ae801595fc882755dc1928640bb')
+
+
+build() {
+ cc -Wall slogin.c -o slogin -lpam -lpam_misc -lutil
+}
+
+package() {
+ # Install SystemD related files
+ install -D -m644 ttyd.service "${pkgdir}/usr/lib/systemd/system/ttyd.service"
+
+ # Install simplified login devoid of signal-handling
+ install -D -m755 slogin "${pkgdir}/usr/bin/slogin"
+}
+
diff --git a/slogin.c b/slogin.c
new file mode 100644
index 000000000000..95f5bea5ce76
--- /dev/null
+++ b/slogin.c
@@ -0,0 +1,174 @@
+/* Simple login program for use with ttyd
+ Original login does not work well with ttyd
+
+ Build with:
+ cc -Wall slogin.c -o slogin -lpam -lpam_misc -lutil
+
+ Elmar Klausmeier, 24-Jul-2020
+*/
+
+#include <stdio.h>
+#include <stdlib.h> // for setenv()
+#include <security/pam_appl.h>
+#include <security/pam_misc.h>
+#include <sys/types.h>
+#include <sys/time.h> // for gettimeofday()
+#include <sys/wait.h> // for wait()
+#include <pwd.h> // for getpwnam()
+#include <grp.h> // for initgroups()
+#include <errno.h>
+#include <utmp.h> // for logwtmp() + login() + logout()
+//#include <utmpx.h> // for struct utmpx, in Linux utmpx and utmp are the same
+
+
+extern char **environ;
+
+
+int main(int argc, char *argv[]) {
+ int rc, flag=1;
+ struct pam_conv conv = { misc_conv, NULL }; // Linux-PAM conversation function
+ pam_handle_t *pamh = NULL;
+ char *p, username[256], arg0[256], *termenv;
+ struct passwd *pwd;
+ struct utmp ut;
+ struct timeval tv;
+ pid_t pid = getpid(), child_pid;
+
+
+ while (flag) {
+ rc = pam_start("login",NULL,&conv,&pamh);
+ if (rc != PAM_SUCCESS) {
+ printf("%s: pam_start() returned %d = %s\n",
+ argv[0],rc,pam_strerror(pamh,rc));
+ pam_end(pamh,0);
+ return 1;
+ }
+
+ rc = pam_authenticate(pamh, 0);
+ if (rc != PAM_SUCCESS) {
+ pam_get_item(pamh, PAM_USER, (const void**)&p);
+ printf("%s: pam_authenticate() for |%s| returned %d = %s\n",
+ argv[0],p,rc,pam_strerror(pamh,rc));
+ // log in btmp, see log_btmp() in login.c
+ memset(&ut, 0, sizeof(ut));
+ strncpy(ut.ut_user,p ? p : "(unknown)",UT_NAMESIZE);
+ ut.ut_user[UT_NAMESIZE] = '\0';
+ strcpy(ut.ut_line,"Hiawatha-ttyd");
+ gettimeofday(&tv, NULL);
+ ut.ut_tv.tv_sec = tv.tv_sec;
+ ut.ut_tv.tv_usec = tv.tv_usec;
+ ut.ut_type = LOGIN_PROCESS;
+ ut.ut_pid = pid;
+ strcpy(ut.ut_host,"Hiawatha-localhost");
+ updwtmp("/var/log/btmp", &ut);
+ } else {
+ rc = pam_get_item(pamh, PAM_USER, (const void**)&p);
+ if (rc != PAM_SUCCESS) {
+ printf("%s: pam_get_item() returned %d = %s\n",
+ argv[0],rc,pam_strerror(pamh,rc));
+ pam_end(pamh,0);
+ return 2;
+ }
+ if (p[0] == '\0') return 3;
+ if (strlen(p) > 255) return 4;
+ strcpy(username,p);
+ flag = 0;
+ }
+
+ rc = pam_end(pamh, 0);
+ if (rc != PAM_SUCCESS) {
+ printf("%s: pam_end() returned %d = %s\n",
+ argv[0],rc,pam_strerror(pamh,rc));
+ return 3;
+ }
+ }
+
+ printf("username = |%s|\n",username);
+ if ((pwd = getpwnam(username)) == NULL) return 4;
+ printf("pw_uid = %d, pw_gid = %d, pw_shell = %s\n",
+ pwd->pw_uid, pwd->pw_gid, pwd->pw_shell);
+
+ //logwtmp("ttyd",username,"hiawatha");
+ memset(&ut, 0, sizeof(ut));
+ strncpy(ut.ut_user,username,UT_NAMESIZE);
+ ut.ut_user[UT_NAMESIZE] = '\0';
+ //strcpy(ut.ut_line,"Hiawatha-ttyd");
+ strcpy(ut.ut_line,ttyname(1)+5);
+ gettimeofday(&tv, NULL);
+ ut.ut_tv.tv_sec = tv.tv_sec;
+ ut.ut_tv.tv_usec = tv.tv_usec;
+ ut.ut_type = LOGIN_PROCESS;
+ ut.ut_pid = pid;
+ strcpy(ut.ut_host,"Hiawatha-localhost");
+ //updwtmp("/run/utmp", &ut);
+ //updwtmp("/var/log/wtmp", &ut);
+ login(&ut); // works well for root
+ printf("ut_user=|%s|, ut_line=|%s|, ut_pid=%d, ut_host=|%s|\n",
+ ut.ut_user, ut.ut_line, ut.ut_pid, ut.ut_host);
+
+ if ((child_pid = fork()) < 0) {
+ printf("%s: cannot fork, %s\n", argv[0],strerror(errno));
+ return 4;
+ } else if (child_pid > 0) { // parent
+ close(0);
+ close(1);
+ close(2);
+ // wait as long as any child is there
+ while (wait(NULL) == -1 && errno == EINTR)
+ ;
+ logout(ut.ut_line);
+ return 0;
+ }
+
+ // Child
+ setsid(); // start new session
+ /* Copied from login.c
+ * For root we don't call initgroups, instead we call setgroups with
+ * group 0. This avoids the need to step through the whole group file,
+ * which can cause problems if NIS, NIS+, LDAP or something similar
+ * is used and the machine has network problems.
+ */
+ rc = pwd->pw_uid ? initgroups(username, pwd->pw_gid) : setgroups(0, NULL);
+ if (rc) {
+ printf("%s: initgroups() returned %d, %s\n",
+ argv[0], rc, strerror(errno));
+ return 8;
+ }
+
+ termenv = getenv("TERM");
+ environ = calloc(1,sizeof(char*));
+ setenv("HOME",pwd->pw_dir,1);
+ setenv("USER",pwd->pw_name,1);
+ setenv("SHELL",pwd->pw_shell,1);
+ setenv("TERM",termenv ? termenv : "dumb",1);
+
+ // First change group, then uid because non-root cannot set group
+ if ((rc = setgid(pwd->pw_gid)) != 0) {
+ printf("%s: setgid() returned %d, %s\n",
+ argv[0], rc, strerror(errno));
+ return 9;
+ }
+ if ((rc = setuid(pwd->pw_uid)) != 0) {
+ printf("%s: setuid() returned %d, %s\n",
+ argv[0], rc, strerror(errno));
+ return 10;
+ }
+
+ if ((rc = chdir(pwd->pw_dir)) != 0) {
+ printf("%s: chdir(\"%s\") returned %d, %s\n",
+ argv[0], pwd->pw_dir, rc, strerror(errno));
+ return 11;
+ }
+
+ if (strchr(pwd->pw_shell, ' ')) {
+ printf("%s: pw_shell=|%s| contains space\n", argv[0], pwd->pw_shell);
+ //return 12;
+ }
+ arg0[0] = '-';
+ strncpy(arg0+1,(p = strrchr(pwd->pw_shell,'/')) ? p+1 : pwd->pw_shell,254);
+ arg0[255] = '\0';
+ execl(pwd->pw_shell,arg0,NULL);
+
+ return 0; // never reached after execl()
+}
+
diff --git a/ttyd.service b/ttyd.service
new file mode 100644
index 000000000000..dde1388a09a5
--- /dev/null
+++ b/ttyd.service
@@ -0,0 +1,18 @@
+[Unit]
+Description=ttyd daemon
+Documentation=man:ttyd(1)
+After=network.target systemd-tmpfiles-clean.service
+Wants=hiawatha.service
+
+[Service]
+Type=simple
+ExecStart=/bin/ttyd /bin/slogin
+ExecReload=/bin/kill -HUP $MAINPID
+#PIDFile=/run/ttyd.pid
+KillMode=process
+LimitNOFILE=512
+LimitMEMLOCK=infinity
+LimitSTACK=infinity
+
+[Install]
+WantedBy=multi-user.target