From 2b9cd1bafde978c17d30b6fe2937806c6308b89b Mon Sep 17 00:00:00 2001 From: Russtopia Date: Sat, 6 Jul 2019 00:23:16 -0700 Subject: [PATCH 1/7] Update 'README.md' --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index ec6fe95..cb956fc 100644 --- a/README.md +++ b/README.md @@ -10,8 +10,8 @@ Golang bindings for basic login/utmp accounting type UtmpEntry struct{ ... } -func Put_lastlog_entry(app string, usr string, host string) +func Put_lastlog_entry(app, usr, ptsname, host string) func Unput_utmp(entry UtmpEntry) -func Put_utmp(user string, host string) UtmpEntry +func Put_utmp(user, ptsname, host string) UtmpEntry ``` From c076bc0153e2d539710f839ae9dca98dcd04f795 Mon Sep 17 00:00:00 2001 From: Russ Magee Date: Sun, 26 Apr 2020 00:50:02 +0000 Subject: [PATCH 2/7] FreeBSD 12 support --- goutmp_bsd.go | 135 ++++++++++++++++++++++++++++++++ goutmp.go => goutmp_linux.go | 1 + main/test_bsd.go | 17 ++++ main/{test.go => test_linux.go} | 1 + 4 files changed, 154 insertions(+) create mode 100644 goutmp_bsd.go rename goutmp.go => goutmp_linux.go (99%) create mode 100644 main/test_bsd.go rename main/{test.go => test_linux.go} (94%) diff --git a/goutmp_bsd.go b/goutmp_bsd.go new file mode 100644 index 0000000..9523354 --- /dev/null +++ b/goutmp_bsd.go @@ -0,0 +1,135 @@ +// +build bsd +// Golang bindings for basic login/utmp accounting +package goutmp + +//#include +//#include +//#include +//#include +//#include +//#include +//#include +//#include +// +//#include +// +//typedef char char_t; +// +//void pututmpx(struct utmpx* entry, char* uname, char* ptsname, char* host) { +// entry->ut_type = USER_PROCESS; +// entry->ut_pid = getpid(); +// strcpy(entry->ut_line, ptsname + strlen("/dev/")); +// +// strcpy(entry->ut_id, ptsname + strlen("/dev/pts/")); +// +// //entry->ut_time = time(NULL); +// strcpy(entry->ut_user, uname); +// strcpy(entry->ut_host, host); +// //entry->ut_addr = 0; +// setutxent(); +// pututxline(entry); +//} +// +//void unpututmpx(struct utmpx* entry) { +// entry->ut_type = DEAD_PROCESS; +// entry->ut_line[0] = '\0'; +// //entry->ut_time = 0; +// entry->ut_user[0] = '\0'; +// setutxent(); +// pututxline(entry); +// +// endutxent(); +//} +// +//#if 0 +//int putlastlogentry(int64_t t, int uid, char* line, char* host) { +// int retval = 0; +// FILE *f; +// struct lastlog l; +// +// strncpy(l.ll_line, line, UT_LINESIZE); +// l.ll_line[UT_LINESIZE-1] = '\0'; +// strncpy(l.ll_host, host, UT_HOSTSIZE); +// l.ll_host[UT_HOSTSIZE-1] = '\0'; +// +// l.ll_time = (time_t)t; +// //printf("l: ll_line '%s', ll_host '%s', ll_time %d\n", l.ll_line, l.ll_host, l.ll_time); +// +// /* Write lastlog entry at fixed offset (uid * sizeof(struct lastlog) */ +// if( NULL != (f = fopen("/var/log/lastlog", "rw+")) ) { +// if( !fseek(f, (uid * sizeof(struct lastlog)), SEEK_SET) ) { +// int fd = fileno(f); +// if( write(fd, &l, sizeof(l)) == sizeof(l) ) { +// retval = 1; +// //int32_t stat = system("echo ---- lastlog ----; lastlog"); +// } +// } +// fclose(f); +// } +// return retval; +//} +//#else +//int putlastlogentry(int64_t t, int uid, char* line, char* host) { +// return 0; +//} +//#endif +import "C" + +import ( + "fmt" + "net" + "os/user" + "strings" + "time" +) + +// UtmpEntry wraps the C struct utmp +type UtmpEntry struct { + entry C.struct_utmpx +} + +// return remote client hostname or IP if host lookup fails +// addr is expected to be of the format given by net.Addr.String() +// eg., "127.0.0.1:80" or "[::1]:80" +func GetHost(addr string) (h string) { + if !strings.Contains(addr, "[") { + h = strings.Split(addr, ":")[0] + } else { + h = strings.Split(strings.Split(addr, "[")[1], "]")[0] + } + hList, e := net.LookupAddr(h) + //fmt.Printf("lookupAddr:%v\n", hList) + if e == nil { + h = hList[0] + } + return +} + +// Put a username and the originating host/IP to utmp +func Put_utmp(user, ptsName, host string) UtmpEntry { + var entry UtmpEntry + + //log.Println("Put_utmp:host ", host, " user ", user) + C.pututmpx(&entry.entry, C.CString(user), C.CString(ptsName), C.CString(host)) + return entry +} + +// Remove a username/host entry from utmp +func Unput_utmp(entry UtmpEntry) { + C.unpututmpx(&entry.entry) +} + +// Put the login app, username and originating host/IP to lastlog +func Put_lastlog_entry(app, usr, ptsname, host string) { + u, e := user.Lookup(usr) + if e != nil { + return + } + var uid uint32 + fmt.Sscanf(u.Uid, "%d", &uid) + + t := time.Now().Unix() + _ = C.putlastlogentry(C.int64_t(t), C.int(uid), C.CString(app), C.CString(host)) + //stat := C.putlastlogentry(C.int64_t(t), C.int(uid), C.CString(app), C.CString(host)) + //fmt.Println("stat was:",stat) +} diff --git a/goutmp.go b/goutmp_linux.go similarity index 99% rename from goutmp.go rename to goutmp_linux.go index 2d7721b..7282f3f 100644 --- a/goutmp.go +++ b/goutmp_linux.go @@ -1,3 +1,4 @@ +// +build linux // Golang bindings for basic login/utmp accounting package goutmp diff --git a/main/test_bsd.go b/main/test_bsd.go new file mode 100644 index 0000000..bc41eb9 --- /dev/null +++ b/main/test_bsd.go @@ -0,0 +1,17 @@ +// +build bsd +package main + +import ( + "time" + + "blitter.com/go/goutmp" +) + +func main() { + user := "bin" + host := "test.example.com" + utmp := goutmp.Put_utmp(user, "/dev/pts0", host) + goutmp.Put_lastlog_entry("hkexsh", user, "/dev/pts0", host) + time.Sleep(10 * time.Second) + goutmp.Unput_utmp(utmp) +} diff --git a/main/test.go b/main/test_linux.go similarity index 94% rename from main/test.go rename to main/test_linux.go index 6b67001..c53b928 100644 --- a/main/test.go +++ b/main/test_linux.go @@ -1,3 +1,4 @@ +// +build linux package main import ( From 74d785142e7a4ea8990df05189e70276bbd5a339 Mon Sep 17 00:00:00 2001 From: Russ Magee Date: Sat, 25 Apr 2020 18:39:08 -0700 Subject: [PATCH 3/7] Fixed +build constraints Signed-off-by: Russ Magee --- goutmp_bsd.go | 1 + goutmp_linux.go | 1 + 2 files changed, 2 insertions(+) diff --git a/goutmp_bsd.go b/goutmp_bsd.go index 9523354..833dcd8 100644 --- a/goutmp_bsd.go +++ b/goutmp_bsd.go @@ -1,4 +1,5 @@ // +build bsd + // Golang bindings for basic login/utmp accounting package goutmp diff --git a/goutmp_linux.go b/goutmp_linux.go index 7282f3f..10513b2 100644 --- a/goutmp_linux.go +++ b/goutmp_linux.go @@ -1,4 +1,5 @@ // +build linux + // Golang bindings for basic login/utmp accounting package goutmp From c3193d4a774614dc64b5c5f8810f01eb5f973aac Mon Sep 17 00:00:00 2001 From: Russ Magee Date: Sat, 25 Apr 2020 19:42:32 -0700 Subject: [PATCH 4/7] More fixes to +build constraints (oops, freebsd not bsd) Signed-off-by: Russ Magee --- goutmp_bsd.go | 2 +- main/test_bsd.go | 3 ++- main/test_linux.go | 1 + 3 files changed, 4 insertions(+), 2 deletions(-) diff --git a/goutmp_bsd.go b/goutmp_bsd.go index 833dcd8..4aada2d 100644 --- a/goutmp_bsd.go +++ b/goutmp_bsd.go @@ -1,4 +1,4 @@ -// +build bsd +// +build freebsd // Golang bindings for basic login/utmp accounting package goutmp diff --git a/main/test_bsd.go b/main/test_bsd.go index bc41eb9..f9d63fb 100644 --- a/main/test_bsd.go +++ b/main/test_bsd.go @@ -1,4 +1,5 @@ -// +build bsd +// +build freebsd + package main import ( diff --git a/main/test_linux.go b/main/test_linux.go index c53b928..8c5275c 100644 --- a/main/test_linux.go +++ b/main/test_linux.go @@ -1,4 +1,5 @@ // +build linux + package main import ( From 826b4de2a3bfe2980dc26c39e2a6d896fe120f54 Mon Sep 17 00:00:00 2001 From: Russ Magee Date: Sat, 19 Mar 2022 00:13:23 -0700 Subject: [PATCH 5/7] Added missing arg for linux test --- main/test_bsd.go | 2 +- main/test_linux.go | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/main/test_bsd.go b/main/test_bsd.go index f9d63fb..8b0b25d 100644 --- a/main/test_bsd.go +++ b/main/test_bsd.go @@ -12,7 +12,7 @@ func main() { user := "bin" host := "test.example.com" utmp := goutmp.Put_utmp(user, "/dev/pts0", host) - goutmp.Put_lastlog_entry("hkexsh", user, "/dev/pts0", host) + goutmp.Put_lastlog_entry("xs", user, "/dev/pts0", host) time.Sleep(10 * time.Second) goutmp.Unput_utmp(utmp) } diff --git a/main/test_linux.go b/main/test_linux.go index 8c5275c..2a60b29 100644 --- a/main/test_linux.go +++ b/main/test_linux.go @@ -11,8 +11,8 @@ import ( func main() { user := "bin" host := "test.example.com" - utmp := goutmp.Put_utmp(user, host) - goutmp.Put_lastlog_entry("hkexsh", user, host) + utmp := goutmp.Put_utmp(user, "/dev/pts0", host) + goutmp.Put_lastlog_entry("xs", user, "/dev/pts0", host) time.Sleep(10 * time.Second) goutmp.Unput_utmp(utmp) } From e75ee8b119512d793b3b7d4c02cb7be735e3254d Mon Sep 17 00:00:00 2001 From: Russ Magee Date: Sat, 19 Mar 2022 09:01:33 -0700 Subject: [PATCH 6/7] go.mod --- go.mod | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 go.mod diff --git a/go.mod b/go.mod new file mode 100644 index 0000000..0ea386d --- /dev/null +++ b/go.mod @@ -0,0 +1,3 @@ +module blitter.com/go/goutmp + +go 1.17 From 73aea4ba722239627b7bcd9c70d0edb1d0a1198b Mon Sep 17 00:00:00 2001 From: Russtopia Date: Thu, 2 Feb 2023 19:01:13 -0800 Subject: [PATCH 7/7] Update 'README.md' --- README.md | 24 +++++++++++++++++++++--- 1 file changed, 21 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index cb956fc..ef45cad 100644 --- a/README.md +++ b/README.md @@ -3,15 +3,33 @@ goutmp - Minimal bindings to C stdlib pututmpx(), getutmpx() (/var/log/wtmp) and Any Go program which allows user shell access should update the standard UNIX files which track user sessions: /var/log/wtmp (for the 'w' and 'who' commands), and /var/log/lastlog (the 'last' and 'lastlog' commands). ``` -go doc +$ go doc -all package goutmp // import "blitter.com/go/goutmp" Golang bindings for basic login/utmp accounting -type UtmpEntry struct{ ... } +FUNCTIONS + +func GetHost(addr string) (h string) + return remote client hostname or IP if host lookup fails addr is expected to + be of the format given by net.Addr.String() eg., "127.0.0.1:80" or + "[::1]:80" func Put_lastlog_entry(app, usr, ptsname, host string) + Put the login app, username and originating host/IP to lastlog + func Unput_utmp(entry UtmpEntry) -func Put_utmp(user, ptsname, host string) UtmpEntry + Remove a username/host entry from utmp + + +TYPES + +type UtmpEntry struct { + // Has unexported fields. +} + UtmpEntry wraps the C struct utmp + +func Put_utmp(user, ptsName, host string) UtmpEntry + Put a username and the originating host/IP to utmp ```