From 526084059fdcc1a8001e403e9861bd7d8febf8d4 Mon Sep 17 00:00:00 2001 From: Anton Novojilov Date: Wed, 24 Jul 2019 14:50:12 +0300 Subject: [PATCH] Added new action 'lib-linked' --- COOKBOOK.md | 24 +++++++++++ README.md | 4 +- action/libs.go | 75 ++++++++++++++++++++++++++++++++ cli/cli.go | 2 +- cli/executor/executor.go | 92 ++++++++++++++++++++-------------------- recipe/tokens.go | 2 + 6 files changed, 151 insertions(+), 48 deletions(-) diff --git a/COOKBOOK.md b/COOKBOOK.md index 3c53ff6a..fd0170c2 100644 --- a/COOKBOOK.md +++ b/COOKBOOK.md @@ -72,6 +72,7 @@ * [`lib-header`](#lib-header) * [`lib-config`](#lib-config) * [`lib-exist`](#lib-exist) + * [`lib-linked`](#lib-linked) * [Examples](#examples) ## Recipe Syntax @@ -1524,6 +1525,29 @@ command "-" "Check environment"
+##### `lib-linked` + +Checks if binary file has link with given library. + +**Syntax:** `lib-linked ` + +**Arguments:** + +* `binary` - Path to binary file (_String_) +* `glob` - Shared library file name glob (_String_) + +**Negative form:** Yes + +**Example:** + +```yang +command "-" "Check environment" + lib-linked /usr/bin/myapp libc.so.* + +``` + +
+ ## Examples ```yang diff --git a/README.md b/README.md index 53501e96..6835c55d 100644 --- a/README.md +++ b/README.md @@ -41,7 +41,9 @@ go get -u github.com/essentialkaos/bibop #### Prebuilt binaries -You can download prebuilt binaries for Linux from [EK Apps Repository](https://apps.kaos.st/bibop/latest): +You can download prebuilt binaries for Linux from [EK Apps Repository](https://apps.kaos.st/bibop/latest). + +To install the latest prebuilt version of bibop, do: ```bash bash <(curl -fsSL https://apps.kaos.st/get) bibop diff --git a/action/libs.go b/action/libs.go index f43a55ff..3c5e4c47 100644 --- a/action/libs.go +++ b/action/libs.go @@ -144,6 +144,36 @@ func LibExist(action *recipe.Action) error { return nil } +// LibLinked is action processor for "lib-linked" +func LibLinked(action *recipe.Action) error { + binary, err := action.GetS(0) + + if err != nil { + return err + } + + lib, err := action.GetS(1) + + if err != nil { + return err + } + + isLinked, err := isLibLinked(binary, lib) + + if err != nil { + return fmt.Errorf("Can't get info from binary: %v", err) + } + + switch { + case !action.Negative && !isLinked: + return fmt.Errorf("Binary %s is not linked with shared library %s", binary, lib) + case action.Negative && isLinked: + return fmt.Errorf("Binary %s is linked with shared library %s", binary, lib) + } + + return nil +} + // ////////////////////////////////////////////////////////////////////////////////// // func isLibLoaded(glob string) (bool, error) { @@ -171,3 +201,48 @@ func isLibLoaded(glob string) (bool, error) { return false, nil } + +func isLibLinked(elf, glob string) (bool, error) { + links, err := getLinkedLibs(elf) + + if err != nil { + return false, err + } + + for _, lib := range links { + match, _ := filepath.Match(glob, lib) + + if match { + return true, nil + } + } + + return false, nil +} + +func getLinkedLibs(elf string) ([]string, error) { + var result []string + + cmd := exec.Command("readelf", "-d", elf) + output, err := cmd.Output() + + if err != nil { + return nil, err + } + + for _, line := range strings.Split(string(output), "\n") { + if !strings.Contains(line, "Shared library:") { + continue + } + + libNameIndex := strings.Index(line, "[") + + if libNameIndex == -1 { + continue + } + + result = append(result, strings.Trim(line[libNameIndex:], "[]")) + } + + return result, nil +} diff --git a/cli/cli.go b/cli/cli.go index 0e7ced78..fb916c7e 100644 --- a/cli/cli.go +++ b/cli/cli.go @@ -33,7 +33,7 @@ import ( // Application info const ( APP = "bibop" - VER = "1.3.0" + VER = "1.4.0" DESC = "Utility for testing command-line tools" ) diff --git a/cli/executor/executor.go b/cli/executor/executor.go index 1b0a6653..538945e9 100644 --- a/cli/executor/executor.go +++ b/cli/executor/executor.go @@ -67,52 +67,52 @@ type ValidationConfig struct { // ////////////////////////////////////////////////////////////////////////////////// // var handlers = map[string]action.Handler{ - "wait": action.Wait, - "sleep": action.Wait, - "chdir": action.Chdir, - "perms": action.Perms, - "owner": action.Owner, - "exist": action.Exist, - "readable": action.Readable, - "writable": action.Writable, - "executable": action.Executable, - "dir": action.Dir, - "empty": action.Empty, - "empty-dir": action.EmptyDir, - "checksum": action.Checksum, - "checksum-read": action.ChecksumRead, - "file-contains": action.FileContains, - "copy": action.Copy, - "move": action.Move, - "touch": action.Touch, - "mkdir": action.Mkdir, - "remove": action.Remove, - "chmod": action.Chmod, - "process-works": action.ProcessWorks, - "wait-pid": action.WaitPID, - "wait-fs": action.WaitFS, - "connect": action.Connect, - "app": action.App, - "env": action.Env, - "env-set": action.EnvSet, - "user-exist": action.UserExist, - "user-id": action.UserID, - "user-gid": action.UserGID, - "user-group": action.UserGroup, - "user-shell": action.UserShell, - "user-home": action.UserHome, - "group-exist": action.GroupExist, - "group-id": action.GroupID, - "service-present": action.ServicePresent, - "service-enabled": action.ServiceEnabled, - "service-works": action.ServiceWorks, - "http-status": action.HTTPStatus, - "http-header": action.HTTPHeader, - "http-contains": action.HTTPContains, - "lib-loaded": action.LibLoaded, - "lib-header": action.LibHeader, - "lib-config": action.LibConfig, - "lib-exist": action.LibExist, + recipe.ACTION_WAIT: action.Wait, + recipe.ACTION_CHDIR: action.Chdir, + recipe.ACTION_PERMS: action.Perms, + recipe.ACTION_OWNER: action.Owner, + recipe.ACTION_EXIST: action.Exist, + recipe.ACTION_READABLE: action.Readable, + recipe.ACTION_WRITABLE: action.Writable, + recipe.ACTION_EXECUTABLE: action.Executable, + recipe.ACTION_DIR: action.Dir, + recipe.ACTION_EMPTY: action.Empty, + recipe.ACTION_EMPTY_DIR: action.EmptyDir, + recipe.ACTION_CHECKSUM: action.Checksum, + recipe.ACTION_CHECKSUM_READ: action.ChecksumRead, + recipe.ACTION_FILE_CONTAINS: action.FileContains, + recipe.ACTION_COPY: action.Copy, + recipe.ACTION_MOVE: action.Move, + recipe.ACTION_TOUCH: action.Touch, + recipe.ACTION_MKDIR: action.Mkdir, + recipe.ACTION_REMOVE: action.Remove, + recipe.ACTION_CHMOD: action.Chmod, + recipe.ACTION_PROCESS_WORKS: action.ProcessWorks, + recipe.ACTION_WAIT_PID: action.WaitPID, + recipe.ACTION_WAIT_FS: action.WaitFS, + recipe.ACTION_CONNECT: action.Connect, + recipe.ACTION_APP: action.App, + recipe.ACTION_ENV: action.Env, + recipe.ACTION_ENV_SET: action.EnvSet, + recipe.ACTION_USER_EXIST: action.UserExist, + recipe.ACTION_USER_ID: action.UserID, + recipe.ACTION_USER_GID: action.UserGID, + recipe.ACTION_USER_GROUP: action.UserGroup, + recipe.ACTION_USER_SHELL: action.UserShell, + recipe.ACTION_USER_HOME: action.UserHome, + recipe.ACTION_GROUP_EXIST: action.GroupExist, + recipe.ACTION_GROUP_ID: action.GroupID, + recipe.ACTION_SERVICE_PRESENT: action.ServicePresent, + recipe.ACTION_SERVICE_ENABLED: action.ServiceEnabled, + recipe.ACTION_SERVICE_WORKS: action.ServiceWorks, + recipe.ACTION_HTTP_STATUS: action.HTTPStatus, + recipe.ACTION_HTTP_HEADER: action.HTTPHeader, + recipe.ACTION_HTTP_CONTAINS: action.HTTPContains, + recipe.ACTION_LIB_LOADED: action.LibLoaded, + recipe.ACTION_LIB_HEADER: action.LibHeader, + recipe.ACTION_LIB_CONFIG: action.LibConfig, + recipe.ACTION_LIB_EXIST: action.LibExist, + recipe.ACTION_LIB_LINKED: action.LibLinked, } var temp *tmp.Temp diff --git a/recipe/tokens.go b/recipe/tokens.go index 8a72ed8b..a2b13e72 100644 --- a/recipe/tokens.go +++ b/recipe/tokens.go @@ -71,6 +71,7 @@ const ( ACTION_LIB_HEADER = "lib-header" ACTION_LIB_CONFIG = "lib-config" ACTION_LIB_EXIST = "lib-exist" + ACTION_LIB_LINKED = "lib-linked" ) // ////////////////////////////////////////////////////////////////////////////////// // @@ -160,4 +161,5 @@ var Tokens = []TokenInfo{ {ACTION_LIB_LOADED, 1, 1, false, true}, {ACTION_LIB_HEADER, 1, 1, false, true}, {ACTION_LIB_CONFIG, 1, 1, false, true}, + {ACTION_LIB_LINKED, 2, 2, false, true}, }