diff --git a/.gitignore b/.gitignore index 8775a6a..06b0825 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,8 @@ -nimcache/ -*.html -tests/main \ No newline at end of file +nimcache +tests/* +!tests/*.nim +!tests/nim.cfg +src/* +!src/*.nim +nimsuggest.log +.vscode diff --git a/.travis.yml b/.travis.yml index 795a065..60146f5 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,5 +1,3 @@ - - # Copied from https://github.com/nim-lang/Nim/wiki/TravisCI language: c env: @@ -39,9 +37,7 @@ install: before_script: - export PATH="nim-$BRANCH/bin${PATH:+:$PATH}" script: - - nim c --cc:$CC --verbosity:0 -r pledge.nim - # Optional: build docs. - - nim doc2 --docSeeSrcUrl:https://github.com/euantorano/pledge.nim/blob/master --project pledge.nim + - nim c --cc:$CC --verbosity:0 -r tests/main.nim cache: directories: - nim-master diff --git a/README.md b/README.md index f4ee4a1..7ade06d 100644 --- a/README.md +++ b/README.md @@ -1,24 +1,30 @@ -# pledge.nim +# pledge.nim [![Travis CI Status](https://travis-ci.org/euantorano/pledge.nim.svg?branch=master)](https://travis-ci.org/euantorano/pledge.nim) A wrapper around OpenBSD's pledge(2) systemcall for Nim. ## Installation -This package can be installed using `nimble`: +`pledge` can be installed using Nimble: ``` nimble install pledge ``` +Or add the following to your `.nimble` file: + +``` +# Dependencies + +requires "pledge >= 1.1.0" +``` + ## Usage ```nim import pledge -if not pledge(Promises.Stdio): - # Pledge failed, cannot use stdio - quit(QuitFailure) +pledge(Promises.Stdio) -# As we haven't used pledge to ask to access files, the below will cause the program to be temrinated. +# As we haven't used pledge to ask to access files, the below will cause the program to be temrinated with a SIGABRT. let f = open("/etc/rc.conf") ``` diff --git a/docs/pledge.html b/docs/pledge.html new file mode 100644 index 0000000..8dcfc52 --- /dev/null +++ b/docs/pledge.html @@ -0,0 +1,1317 @@ + + + + + + + + + + + + + + + + + +Module pledge + + + + + + + + +
+
+

Module pledge

+
+
+
+ Search: +
+
+ Group by: + +
+ + +
+
+
+

A wrapper for the pledge(2) systemcall, used to restrict system operations.

+

On systems other than OpenBSD where pledge is not yet implemented, the wrapper has no effect.

+ +

Example of making a single promise

In order to pledge to only use the stdio promise as described in the pledge(2) man page, you simply pass the Promise.Stdio to pledge():

+
import pledge
+
+pledge(Promise.Stdio)
+

Example of making several promises

In order to pledge to use the stdio and rpath promises as described in the pledge(2) man page, you simply pass the required promises to pledge():

+
import pledge
+
+pledge(Promise.Stdio, Promise.Rpath)

+ +
+

Types

+
+
Promise* {.
pure
.} = enum + Stdio = "stdio", Rpath = "rpath", Wpath = "wpath", Cpath = "cpath", Dpath = "dpath", + Tmppath = "tmppath", Inet = "inet", Mcast = "mcast", Fattr = "fattr", Chown = "chown", + Flock = "flock", Unix = "unix", Dns = "dns", Getpw = "getpw", Sendfd = "sendfd", + Recvfd = "recvfd", Tape = "tape", Tty = "tty", Proc = "proc", Exec = "exec", + ProtExec = "prot_exec", Settime = "settime", Ps = "ps", Vminfo = "vminfo", Id = "id", + Pf = "pf", Audio = "audio", Bpf = "bpf"
+
+The possible operation sets that a program can pledge to be limited to. +  Source +Edit + +
+ +
+
+

Procs

+
+
proc pledge*(promises: varargs[Promise]) {.
raises: [OSError]
.}
+
+

Pledge to use only the defined functions. Always returns true on non-OpenBSD systems.

+

If no promises are provided, the process will be restricted to the _exit(2) system call.

+

If the pledge call is not successful, an OSError will be thrown.

+ +  Source +Edit + +
+ +
+ +
+
+ +
+ +
+
+
+ + + diff --git a/docs/pledge.idx b/docs/pledge.idx new file mode 100644 index 0000000..b1a5d98 --- /dev/null +++ b/docs/pledge.idx @@ -0,0 +1,4 @@ +Example of making a single promise pledge.html#example-of-making-a-single-promise Example of making a single promise +Example of making several promises pledge.html#example-of-making-several-promises Example of making several promises +Promise pledge.html#Promise pledge : Promise +pledge pledge.html#pledge,varargs[Promise] pledge : pledge*(promises: varargs[Promise]) diff --git a/pledge.nimble b/pledge.nimble index 4d5880e..c9305c4 100644 --- a/pledge.nimble +++ b/pledge.nimble @@ -1,16 +1,18 @@ -# Package - -version = "1.0.1" -author = "Euan T" -description = "A wrapper around OpenBSD's pledge(2) systemcall for Nim." -license = "BSD" - -# Dependencies - -requires "nim >= 0.13.0" - -task tests, "Run unit tests": - exec "nim c -r tests/main" - -task docs, "Build package documentation": - exec "nim doc2 pledge.nim" \ No newline at end of file +# Package + +version = "1.0.2" +author = "Euan T" +description = "A wrapper around OpenBSD's pledge(2) systemcall for Nim." +license = "BSD3" + +srcDir = "src" + +# Dependencies + +requires "nim >= 0.13.0" + +task tests, "Run unit tests": + exec "nim c -r tests/main" + +task docs, "Build documentation": + exec "nim doc --index:on -o:docs/pledge.html src/pledge.nim" diff --git a/pledge.nim b/src/pledge.nim similarity index 63% rename from pledge.nim rename to src/pledge.nim index 809dfe1..8f3325a 100644 --- a/pledge.nim +++ b/src/pledge.nim @@ -10,7 +10,7 @@ ## .. code-block::nim ## import pledge ## -## let pledged = pledge(Promise.Stdio) +## pledge(Promise.Stdio) ## ## Example of making several promises ## ---------------------------------- @@ -20,7 +20,7 @@ ## .. code-block::nim ## import pledge ## -## let pledged = pledge(Promise.Stdio, Promise.Rpath) +## pledge(Promise.Stdio, Promise.Rpath) from os import osLastError, raiseOSError from sequtils import map, deduplicate @@ -35,49 +35,60 @@ type Promise* {.pure.} = enum Dpath = "dpath", Tmppath = "tmppath", Inet = "inet", + Mcast = "mcast", Fattr = "fattr", + Chown = "chown", Flock = "flock", Unix = "unix", Dns = "dns", Getpw = "getpw", Sendfd = "sendfd", Recvfd = "recvfd", - Ioctl = "ioctl", + Tape = "tape", Tty = "tty", Proc = "proc", Exec = "exec", - Prot_exec = "prot_exec", + ProtExec = "prot_exec", Settime = "settime", Ps = "ps", Vminfo = "vminfo", Id = "id", Pf = "pf", - Audio = "audio" + Audio = "audio", + Bpf = "bpf" when defined(nimdoc): - proc pledge*(promises: varargs[Promise]): bool {.raises: [OSError].} = discard + proc pledge*(promises: varargs[Promise]) {.raises: [OSError].} = discard ## Pledge to use only the defined functions. Always returns true on non-OpenBSD systems. ## - ## If the pledge call was successful, this will return true. + ## If no promises are provided, the process will be restricted to the `_exit(2)` system call. ## ## If the pledge call is not successful, an `OSError` will be thrown. elif defined(openbsd): - proc pledge_c(promises: cstring, paths: cstringArray): cint {.importc: "pledge".} + proc pledge_c(promises: cstring, paths: cstringArray): cint {.importc: "pledge", header: "".} proc promisesToString(promises: openArray[Promise]): string = ## Convert a list of promises to a string for use with the `pledge(2)` function. + if len(promises) == 0: + return "" + let stringPromises = map(promises, proc(p: Promise): string = $p) - return join(deduplicate(stringPromises), " ") + result = join(deduplicate(stringPromises), " ") - proc pledge*(promises: varargs[Promise]): bool {.raises: [OSError].} = + proc pledge*(promises: varargs[Promise]) {.raises: [OSError].} = + ## Pledge to use only the defined functions. Always returns true on non-OpenBSD systems. + ## + ## If no promises are provided, the process will be restricted to the `_exit(2)` system call. + ## + ## If the pledge call is not successful, an `OSError` will be thrown. let promisesString = promisesToString(promises) - let pledged = pledge_c(promisesString, nil) - - if pledged != 0: - let errorCode = osLastError() - raiseOSError(errorCode) - - result = true + if pledge_c(promisesString, nil) != 0: + raiseOSError(osLastError()) else: - proc pledge*(promises: varargs[Promise]): bool = true + proc pledge*(promises: varargs[Promise]) = discard + ## Pledge to use only the defined functions. Always returns true on non-OpenBSD systems. + ## + ## If no promises are provided, the process will be restricted to the `_exit(2)` system call. + ## + ## If the pledge call is not successful, an `OSError` will be thrown. diff --git a/tests/main.nim b/tests/main.nim index 7e2fa4f..4506504 100644 --- a/tests/main.nim +++ b/tests/main.nim @@ -1,12 +1,14 @@ -import ../pledge, unittest, os - -suite "pledge tests": - test "can pledge": - check pledge(Promise.Stdio, Promise.Rpath) - - when defined(openbsd): - test "can not elevate": - check pledge(Promise.Stdio) - - expect OSError: - check pledge(Promise.Stdio, Promise.Rpath) == false +import pledge, unittest, os + +suite "pledge tests": + test "can pledge": + pledge(Promise.Stdio, Promise.Rpath) + + check true + + when defined(openbsd): + test "can not elevate": + pledge(Promise.Stdio) + + expect OSError: + pledge(Promise.Stdio, Promise.Rpath) == false diff --git a/tests/nim.cfg b/tests/nim.cfg index c3a311d..07d0466 100644 --- a/tests/nim.cfg +++ b/tests/nim.cfg @@ -1,2 +1,8 @@ -path=".." -path="." +path: "$projectPath/../src/" +hints: off +linedir: on +debuginfo +stacktrace: on +linetrace: on + +define: test