Skip to content

Commit 984b3a4

Browse files
authored
Merge pull request #1 from TheBestLL/master
兼容windows user表 还有ssh协议公钥查询表
2 parents 7c3aca4 + 0cc9cea commit 984b3a4

File tree

8 files changed

+275
-11
lines changed

8 files changed

+275
-11
lines changed

.gitignore

+2
Original file line numberDiff line numberDiff line change
@@ -2,3 +2,5 @@
22
.DS_Store
33
*.log
44
dist/
5+
vendor/
6+
.vscode/

README.md

+6-1
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,12 @@ func main() {
4141

4242
## Build
4343

44-
go build -tags=sqlite_vtable
44+
* darwin
45+
> go build -tags=sqlite_vtable
46+
* linux
47+
> CGO_ENABLED=1 GOOS=linux CC="x86_64-linux-musl-gcc" GOARCH=amd64 go build -tags=sqlite_vtable -ldflags "-s -w --extldflags "-static""
48+
* windows
49+
> CGO_ENABLED=1 GOOS=windows CC="x86_64-w64-mingw32-gcc" GOARCH=amd64 go build -tags=sqlite_vtable
4550
4651
## Playground
4752
```sql

extend/tables/ssh_keys_table.go

+42
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
//go:build linux
2+
3+
package tables
4+
5+
import (
6+
"github.com/dean2021/sysql/extend/tables/system"
7+
"github.com/dean2021/sysql/table"
8+
)
9+
10+
func init() {
11+
t := &SSHKeysTable{}
12+
err := table.Register(t, t.Name())
13+
if err != nil {
14+
panic(err)
15+
}
16+
}
17+
18+
type SSHKeysTable struct{}
19+
20+
func (p *SSHKeysTable) Name() string {
21+
return "ssh_keys"
22+
}
23+
24+
func (p *SSHKeysTable) Columns() table.TableColumns {
25+
return table.TableColumns{
26+
{Name: "uid", Type: table.BIGINT_TYPE, Options: table.INDEX},
27+
{Name: "path", Type: table.TEXT_TYPE, Options: table.DEFAULT},
28+
{Name: "username", Type: table.TEXT_TYPE, Options: table.DEFAULT},
29+
{Name: "file_name", Type: table.TEXT_TYPE, Options: table.DEFAULT},
30+
{Name: "file_size", Type: table.BIGINT_TYPE, Options: table.DEFAULT},
31+
{Name: "mod_time", Type: table.TEXT_TYPE, Options: table.DEFAULT},
32+
{Name: "key", Type: table.TEXT_TYPE, Options: table.DEFAULT},
33+
}
34+
}
35+
36+
func (p *SSHKeysTable) Generate(context *table.QueryContext) (table.TableRows, error) {
37+
list, err := system.GenSSHKeys(context)
38+
if err != nil {
39+
return nil, err
40+
}
41+
return list, nil
42+
}

extend/tables/system/ssh_keys.go

+65
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
//go:build linux
2+
3+
package system
4+
5+
import (
6+
"bufio"
7+
"os"
8+
"path/filepath"
9+
10+
"github.com/dean2021/sysql/table"
11+
)
12+
13+
var authorizedKeyFileNames = []string{"authorized_keys", "authorized_keys2"}
14+
15+
func GenSSHKeys(context *table.QueryContext) (table.TableRows, error) {
16+
var results table.TableRows
17+
users, err := getUsers()
18+
if err != nil {
19+
return nil, err
20+
}
21+
for _, u := range users {
22+
for _, name := range authorizedKeyFileNames {
23+
//判断是否存在.ssh文件
24+
path := filepath.Join(u.Directory, ".ssh", name)
25+
stat, err := os.Stat(path)
26+
if err != nil {
27+
continue
28+
}
29+
keys, err := getPublicKeys(path)
30+
if err != nil {
31+
return nil, err
32+
}
33+
for _, key := range keys {
34+
results = append(results, table.TableRow{
35+
"uid": u.Uid,
36+
"path": path,
37+
"username": u.Username,
38+
"file_name": name,
39+
"file_size": stat.Size(),
40+
"mod_time": stat.ModTime().Format("2006-01-02 15:04:05"),
41+
"key": key,
42+
})
43+
}
44+
}
45+
}
46+
return results, nil
47+
}
48+
49+
func getPublicKeys(path string) ([]string, error) {
50+
//遍历authorized_keys文件
51+
fi, err := os.Open(path)
52+
if err != nil {
53+
return nil, err
54+
}
55+
defer fi.Close()
56+
var lines []string
57+
scanner := bufio.NewScanner(fi)
58+
for scanner.Scan() {
59+
lines = append(lines, scanner.Text())
60+
}
61+
if err := scanner.Err(); err != nil {
62+
return nil, err
63+
}
64+
return lines, nil
65+
}

extend/tables/system/users.go

+41-10
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,52 @@
1+
//go:build linux || darwin
2+
13
package system
24

35
import (
46
"bufio"
5-
"github.com/dean2021/sysql/extend/tables/common"
6-
"github.com/dean2021/sysql/table"
77
"os"
88
"strings"
9+
10+
"github.com/dean2021/sysql/extend/tables/common"
11+
"github.com/dean2021/sysql/table"
912
)
1013

14+
type User struct {
15+
Uid string `json:"uid"`
16+
Gid string `json:"gid"`
17+
Username string `json:"username"`
18+
Description string `json:"description"`
19+
Directory string `json:"directory"`
20+
Shell string `json:"shell"`
21+
}
22+
1123
func GenUsers(context *table.QueryContext) (table.TableRows, error) {
1224
var results table.TableRows
25+
users, err := getUsers()
26+
if err != nil {
27+
return nil, err
28+
}
29+
for _, u := range users {
30+
results = append(results, table.TableRow{
31+
"uid": u.Uid,
32+
"gid": u.Gid,
33+
"username": u.Username,
34+
"description": u.Description,
35+
"directory": u.Directory,
36+
"shell": u.Shell,
37+
})
38+
}
39+
return results, nil
40+
}
41+
42+
func getUsers() ([]User, error) {
1343
fi, err := os.Open(common.HostEtc("passwd"))
1444
if err != nil {
1545
return nil, err
1646
}
1747
defer fi.Close()
1848
br := bufio.NewReader(fi)
49+
users := []User{}
1950
for {
2051
s, _, err := br.ReadLine()
2152
if err != nil {
@@ -27,15 +58,15 @@ func GenUsers(context *table.QueryContext) (table.TableRows, error) {
2758
if len(items) < 7 {
2859
continue
2960
}
30-
results = append(results, table.TableRow{
31-
"uid": items[2],
32-
"gid": items[3],
33-
"username": items[0],
34-
"description": items[4],
35-
"directory": items[5],
36-
"shell": items[6],
61+
users = append(users, User{
62+
Uid: items[2],
63+
Gid: items[3],
64+
Username: items[0],
65+
Description: items[4],
66+
Directory: items[5],
67+
Shell: items[6],
3768
})
3869
}
3970
}
40-
return results, nil
71+
return users, nil
4172
}

extend/tables/system/users_windows.go

+65
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
//go:build windows
2+
// +build windows
3+
4+
package system
5+
6+
import (
7+
"github.com/dean2021/sysql/table"
8+
"github.com/yusufpapurcu/wmi"
9+
)
10+
11+
type Win32UserAccount struct {
12+
AccountType int64 `json:"accountType"`
13+
Caption string `json:"caption"`
14+
Description string `json:"description"`
15+
Disabled bool `json:"disabled"`
16+
Domain string `json:"domain"`
17+
FullName string `json:"fullName"`
18+
InstallDate string `json:"installDate"`
19+
LocalAccount bool `json:"localAccount"`
20+
Lockout bool `json:"lockout"`
21+
PasswordChangeable bool `json:"passwordChangeable"`
22+
PasswordExpires bool `json:"passwordExpires"`
23+
PasswordRequired bool `json:"passwordRequired"`
24+
Name string `json:"name"`
25+
SID string `json:"sid"`
26+
SIDType int64 `json:"sidType"`
27+
Status string `json:"status"`
28+
}
29+
30+
func getWin32UserAccount() ([]Win32UserAccount, error) {
31+
var s []Win32UserAccount
32+
err := wmi.Query("SELECT * FROM Win32_UserAccount WHERE LocalAccount=True", &s)
33+
if err != nil {
34+
return nil, err
35+
}
36+
return s, nil
37+
}
38+
func GenUsers(context *table.QueryContext) (table.TableRows, error) {
39+
var results table.TableRows
40+
accounts, err := getWin32UserAccount()
41+
if err != nil {
42+
return nil, err
43+
}
44+
for _, a := range accounts {
45+
results = append(results, table.TableRow{
46+
"accountType": a.AccountType,
47+
"caption": a.Caption,
48+
"description": a.Description,
49+
"disabled": a.Disabled,
50+
"domain": a.Domain,
51+
"fullName": a.FullName,
52+
"installDate": a.InstallDate,
53+
"localAccount": a.LocalAccount,
54+
"lockout": a.Lockout,
55+
"passwordChangeable": a.PasswordChangeable,
56+
"passwordExpires": a.PasswordExpires,
57+
"passwordRequired": a.PasswordRequired,
58+
"name": a.Name,
59+
"sid": a.SID,
60+
"sidType": a.SIDType,
61+
"status": a.Status,
62+
})
63+
}
64+
return results, nil
65+
}

extend/tables/users_table.go

+2
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
//go:build linux
2+
13
package tables
24

35
import (

extend/tables/users_table_windows.go

+52
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
//go:build windows
2+
// +build windows
3+
4+
package tables
5+
6+
import (
7+
"github.com/dean2021/sysql/extend/tables/system"
8+
"github.com/dean2021/sysql/table"
9+
)
10+
11+
func init() {
12+
t := &UsersTable{}
13+
err := table.Register(t, t.Name())
14+
if err != nil {
15+
panic(err)
16+
}
17+
}
18+
19+
type UsersTable struct{}
20+
21+
func (p *UsersTable) Name() string {
22+
return "users"
23+
}
24+
25+
func (p *UsersTable) Columns() table.TableColumns {
26+
return table.TableColumns{
27+
{Name: "sid", Type: table.TEXT_TYPE, Options: table.INDEX},
28+
{Name: "name", Type: table.TEXT_TYPE, Options: table.DEFAULT},
29+
{Name: "accountType", Type: table.INTEGER_TYPE, Options: table.DEFAULT},
30+
{Name: "caption", Type: table.TEXT_TYPE, Options: table.DEFAULT},
31+
{Name: "description", Type: table.TEXT_TYPE, Options: table.DEFAULT},
32+
{Name: "disabled", Type: table.INTEGER_TYPE, Options: table.DEFAULT}, // Assuming boolean is represented as integer
33+
{Name: "domain", Type: table.TEXT_TYPE, Options: table.DEFAULT},
34+
{Name: "fullName", Type: table.TEXT_TYPE, Options: table.DEFAULT},
35+
{Name: "installDate", Type: table.TEXT_TYPE, Options: table.DEFAULT},
36+
{Name: "localAccount", Type: table.INTEGER_TYPE, Options: table.DEFAULT}, // Assuming boolean is represented as integer
37+
{Name: "lockout", Type: table.INTEGER_TYPE, Options: table.DEFAULT}, // Assuming boolean is represented as integer
38+
{Name: "passwordChangeable", Type: table.INTEGER_TYPE, Options: table.DEFAULT}, // Assuming boolean is represented as integer
39+
{Name: "passwordExpires", Type: table.INTEGER_TYPE, Options: table.DEFAULT}, // Assuming boolean is represented as integer
40+
{Name: "passwordRequired", Type: table.INTEGER_TYPE, Options: table.DEFAULT}, // Assuming boolean is represented as integer
41+
{Name: "sidType", Type: table.INTEGER_TYPE, Options: table.DEFAULT},
42+
{Name: "status", Type: table.TEXT_TYPE, Options: table.DEFAULT},
43+
}
44+
}
45+
46+
func (p *UsersTable) Generate(context *table.QueryContext) (table.TableRows, error) {
47+
list, err := system.GenUsers(context)
48+
if err != nil {
49+
return nil, err
50+
}
51+
return list, nil
52+
}

0 commit comments

Comments
 (0)