From 36985345a93ceeb40908b8383e37643c32fb5f0f Mon Sep 17 00:00:00 2001 From: Tarun Koyalwar <45962551+tarunKoyalwar@users.noreply.github.com> Date: Wed, 7 Feb 2024 21:45:40 +0530 Subject: [PATCH] javascript bindings + docs generation enhancements ( generate typescript defination .d.ts files) (#4487) * introduce typescript files generation using ast + tmpl * feat valid ts with scraping * feat remove old logic + tsdocs for all modules * fix ikev and related bugs * typescript docs for js modules * lint,build + ldap realm fix * go mod tidy * fix named imports ast parsing * fix ast code generation errors * complete support for ts files generation * support go global/const in ts docs * updated template * feat: typescript using go code generation * nuke jsdoc generator * update generated ts dir structure * fix multifile ts gen issue * fix panic in ts code gen * fix test * update docs of js libs * feat: add doc+example for every js class,function,method * fix missing quotes in ikev example --------- Co-authored-by: Sandeep Singh --- .gitignore | 3 + Makefile | 10 +- go.mod | 2 +- pkg/js/devtools/README.md | 3 - pkg/js/devtools/bindgen/cmd/bindgen/main.go | 14 +- pkg/js/devtools/bindgen/generator.go | 90 ++- .../devtools/bindgen/templates/go_class.tmpl | 15 +- pkg/js/devtools/jsdocgen/README.md | 116 ---- pkg/js/devtools/jsdocgen/main.go | 178 ------ pkg/js/devtools/tsgen/README.md | 3 + pkg/js/devtools/tsgen/astutil.go | 109 ++++ pkg/js/devtools/tsgen/cmd/tsgen/main.go | 118 ++++ .../devtools/tsgen/cmd/tsgen/tsmodule.go.tmpl | 79 +++ pkg/js/devtools/tsgen/parser.go | 585 ++++++++++++++++++ pkg/js/devtools/tsgen/scrape.go | 192 ++++++ pkg/js/devtools/tsgen/types.go | 60 ++ pkg/js/generated/go/libbytes/bytes.go | 6 +- pkg/js/generated/go/libfs/fs.go | 3 +- pkg/js/generated/go/libgoconsole/goconsole.go | 6 +- pkg/js/generated/go/libikev2/ikev2.go | 13 +- pkg/js/generated/go/libkerberos/kerberos.go | 13 +- pkg/js/generated/go/libldap/ldap.go | 14 +- pkg/js/generated/go/libmssql/mssql.go | 7 +- pkg/js/generated/go/libmysql/mysql.go | 10 +- pkg/js/generated/go/libnet/net.go | 7 +- pkg/js/generated/go/liboracle/oracle.go | 10 +- pkg/js/generated/go/libpop3/pop3.go | 10 +- pkg/js/generated/go/libpostgres/postgres.go | 7 +- pkg/js/generated/go/librdp/rdp.go | 13 +- pkg/js/generated/go/libredis/redis.go | 3 +- pkg/js/generated/go/librsync/rsync.go | 10 +- pkg/js/generated/go/libsmb/smb.go | 7 +- pkg/js/generated/go/libsmtp/smtp.go | 13 +- pkg/js/generated/go/libssh/ssh.go | 7 +- pkg/js/generated/go/libstructs/structs.go | 3 +- pkg/js/generated/go/libtelnet/telnet.go | 10 +- pkg/js/generated/go/libvnc/vnc.go | 10 +- pkg/js/generated/js/global.js | 86 --- pkg/js/generated/js/libbytes/bytes.js | 134 ---- pkg/js/generated/js/libfs/fs.js | 65 -- pkg/js/generated/js/libgoconsole/goconsole.js | 63 -- pkg/js/generated/js/libikev2/ikev2.js | 38 -- pkg/js/generated/js/libkerberos/kerberos.js | 34 - pkg/js/generated/js/libldap/ldap.js | 49 -- pkg/js/generated/js/libmssql/mssql.js | 64 -- pkg/js/generated/js/libmysql/mysql.js | 84 --- pkg/js/generated/js/libnet/net.js | 156 ----- pkg/js/generated/js/liboracle/oracle.js | 33 - pkg/js/generated/js/libpop3/pop3.js | 33 - pkg/js/generated/js/libpostgres/postgres.js | 84 --- pkg/js/generated/js/librdp/rdp.js | 55 -- pkg/js/generated/js/libredis/redis.js | 87 --- pkg/js/generated/js/librsync/rsync.js | 33 - pkg/js/generated/js/libsmb/smb.js | 90 --- pkg/js/generated/js/libsmtp/smtp.js | 152 ----- pkg/js/generated/js/libssh/ssh.js | 112 ---- pkg/js/generated/js/libstructs/structs.js | 54 -- pkg/js/generated/js/libtelnet/telnet.js | 33 - pkg/js/generated/js/libvnc/vnc.js | 33 - pkg/js/generated/ts/bytes.ts | 141 +++++ pkg/js/generated/ts/fs.ts | 78 +++ pkg/js/generated/ts/goconsole.ts | 44 ++ pkg/js/generated/ts/ikev2.ts | 124 ++++ pkg/js/generated/ts/index.ts | 21 + pkg/js/generated/ts/kerberos.ts | 475 ++++++++++++++ pkg/js/generated/ts/ldap.ts | 578 +++++++++++++++++ pkg/js/generated/ts/mssql.ts | 67 ++ pkg/js/generated/ts/mysql.ts | 230 +++++++ pkg/js/generated/ts/net.ts | 183 ++++++ pkg/js/generated/ts/oracle.ts | 49 ++ pkg/js/generated/ts/pop3.ts | 50 ++ pkg/js/generated/ts/postgres.ts | 96 +++ pkg/js/generated/ts/rdp.ts | 112 ++++ pkg/js/generated/ts/redis.ts | 70 +++ pkg/js/generated/ts/rsync.ts | 50 ++ pkg/js/generated/ts/smb.ts | 236 +++++++ pkg/js/generated/ts/smtp.ts | 191 ++++++ pkg/js/generated/ts/ssh.ts | 230 +++++++ pkg/js/generated/ts/structs.ts | 49 ++ pkg/js/generated/ts/telnet.ts | 50 ++ pkg/js/generated/ts/vnc.ts | 51 ++ pkg/js/gojs/gojs.go | 8 + pkg/js/libs/bytes/buffer.go | 105 +++- pkg/js/libs/fs/fs.go | 44 +- pkg/js/libs/ikev2/ikev2.go | 137 ++-- pkg/js/libs/kerberos/kerberosx.go | 129 ++-- pkg/js/libs/kerberos/sendtokdc.go | 7 + pkg/js/libs/ldap/adenum.go | 135 +++- pkg/js/libs/ldap/ldap.go | 156 +++-- pkg/js/libs/ldap/utils.go | 19 +- pkg/js/libs/mssql/mssql.go | 36 +- pkg/js/libs/mysql/mysql.go | 89 ++- pkg/js/libs/mysql/mysql_private.go | 41 +- pkg/js/libs/net/net.go | 101 ++- pkg/js/libs/oracle/oracle.go | 37 +- pkg/js/libs/pop3/pop3.go | 36 +- pkg/js/libs/postgres/postgres.go | 44 +- pkg/js/libs/rdp/rdp.go | 62 +- pkg/js/libs/redis/redis.go | 27 +- pkg/js/libs/rsync/rsync.go | 36 +- pkg/js/libs/smb/smb.go | 44 +- pkg/js/libs/smb/smbghost.go | 6 + pkg/js/libs/smtp/msg.go | 66 +- pkg/js/libs/smtp/smtp.go | 56 +- pkg/js/libs/ssh/ssh.go | 78 ++- pkg/js/libs/structs/structs.go | 16 + pkg/js/libs/telnet/telnet.go | 36 +- pkg/js/libs/vnc/vnc.go | 35 +- 108 files changed, 5716 insertions(+), 2376 deletions(-) delete mode 100644 pkg/js/devtools/jsdocgen/README.md delete mode 100644 pkg/js/devtools/jsdocgen/main.go create mode 100644 pkg/js/devtools/tsgen/README.md create mode 100644 pkg/js/devtools/tsgen/astutil.go create mode 100644 pkg/js/devtools/tsgen/cmd/tsgen/main.go create mode 100644 pkg/js/devtools/tsgen/cmd/tsgen/tsmodule.go.tmpl create mode 100644 pkg/js/devtools/tsgen/parser.go create mode 100644 pkg/js/devtools/tsgen/scrape.go create mode 100644 pkg/js/devtools/tsgen/types.go delete mode 100644 pkg/js/generated/js/global.js delete mode 100644 pkg/js/generated/js/libbytes/bytes.js delete mode 100644 pkg/js/generated/js/libfs/fs.js delete mode 100644 pkg/js/generated/js/libgoconsole/goconsole.js delete mode 100644 pkg/js/generated/js/libikev2/ikev2.js delete mode 100644 pkg/js/generated/js/libkerberos/kerberos.js delete mode 100644 pkg/js/generated/js/libldap/ldap.js delete mode 100644 pkg/js/generated/js/libmssql/mssql.js delete mode 100644 pkg/js/generated/js/libmysql/mysql.js delete mode 100644 pkg/js/generated/js/libnet/net.js delete mode 100644 pkg/js/generated/js/liboracle/oracle.js delete mode 100644 pkg/js/generated/js/libpop3/pop3.js delete mode 100644 pkg/js/generated/js/libpostgres/postgres.js delete mode 100644 pkg/js/generated/js/librdp/rdp.js delete mode 100644 pkg/js/generated/js/libredis/redis.js delete mode 100644 pkg/js/generated/js/librsync/rsync.js delete mode 100644 pkg/js/generated/js/libsmb/smb.js delete mode 100644 pkg/js/generated/js/libsmtp/smtp.js delete mode 100644 pkg/js/generated/js/libssh/ssh.js delete mode 100644 pkg/js/generated/js/libstructs/structs.js delete mode 100644 pkg/js/generated/js/libtelnet/telnet.js delete mode 100644 pkg/js/generated/js/libvnc/vnc.js create mode 100755 pkg/js/generated/ts/bytes.ts create mode 100755 pkg/js/generated/ts/fs.ts create mode 100755 pkg/js/generated/ts/goconsole.ts create mode 100755 pkg/js/generated/ts/ikev2.ts create mode 100755 pkg/js/generated/ts/index.ts create mode 100755 pkg/js/generated/ts/kerberos.ts create mode 100755 pkg/js/generated/ts/ldap.ts create mode 100755 pkg/js/generated/ts/mssql.ts create mode 100755 pkg/js/generated/ts/mysql.ts create mode 100755 pkg/js/generated/ts/net.ts create mode 100755 pkg/js/generated/ts/oracle.ts create mode 100755 pkg/js/generated/ts/pop3.ts create mode 100755 pkg/js/generated/ts/postgres.ts create mode 100755 pkg/js/generated/ts/rdp.ts create mode 100755 pkg/js/generated/ts/redis.ts create mode 100755 pkg/js/generated/ts/rsync.ts create mode 100755 pkg/js/generated/ts/smb.ts create mode 100755 pkg/js/generated/ts/smtp.ts create mode 100755 pkg/js/generated/ts/ssh.ts create mode 100755 pkg/js/generated/ts/structs.ts create mode 100755 pkg/js/generated/ts/telnet.ts create mode 100755 pkg/js/generated/ts/vnc.ts diff --git a/.gitignore b/.gitignore index 31d516da03..614c242184 100644 --- a/.gitignore +++ b/.gitignore @@ -20,11 +20,14 @@ pkg/protocols/common/helpers/deserialization/testdata/ValueObject2.ser .gitignore pkg/js/devtools/bindgen/cmd/bindgen/bindgen pkg/js/devtools/jsdocgen/jsdocgen +pkg/js/devtools/tsgen/tsgen +pkg/js/devtools/tsgen/cmd/tsgen/tsgen *.DS_Store pkg/protocols/headless/engine/.cache /nuclei /bindgen /jsdocgen +/tsgen /scrapefuncs /integration_tests/.cache/ /integration_tests/.nuclei-config/ diff --git a/Makefile b/Makefile index 6de70c7b1b..1ddf950e88 100644 --- a/Makefile +++ b/Makefile @@ -32,6 +32,14 @@ tidy: $(GOMOD) tidy devtools: $(GOBUILD) $(GOFLAGS) -ldflags '$(LDFLAGS)' -o "bindgen" pkg/js/devtools/bindgen/cmd/bindgen/main.go - $(GOBUILD) $(GOFLAGS) -ldflags '$(LDFLAGS)' -o "jsdocgen" pkg/js/devtools/jsdocgen/main.go + $(GOBUILD) $(GOFLAGS) -ldflags '$(LDFLAGS)' -o "tsgen" pkg/js/devtools/tsgen/cmd/tsgen/main.go $(GOBUILD) $(GOFLAGS) -ldflags '$(LDFLAGS)' -o "scrapefuncs" pkg/js/devtools/scrapefuncs/main.go +jsupdate: + $(GOBUILD) $(GOFLAGS) -ldflags '$(LDFLAGS)' -o "bindgen" pkg/js/devtools/bindgen/cmd/bindgen/main.go + $(GOBUILD) $(GOFLAGS) -ldflags '$(LDFLAGS)' -o "tsgen" pkg/js/devtools/tsgen/cmd/tsgen/main.go + ./bindgen -dir pkg/js/libs -out pkg/js/generated + ./tsgen -dir pkg/js/libs -out pkg/js/generated/ts +ts: + $(GOBUILD) $(GOFLAGS) -ldflags '$(LDFLAGS)' -o "tsgen" pkg/js/devtools/tsgen/cmd/tsgen/main.go + ./tsgen -dir pkg/js/libs -out pkg/js/generated/ts diff --git a/go.mod b/go.mod index 05269b1ab7..1db6528f4b 100644 --- a/go.mod +++ b/go.mod @@ -288,7 +288,7 @@ require ( golang.org/x/mod v0.14.0 // indirect golang.org/x/sys v0.16.0 // indirect golang.org/x/time v0.3.0 // indirect - golang.org/x/tools v0.17.0 // indirect + golang.org/x/tools v0.17.0 google.golang.org/appengine v1.6.7 // indirect google.golang.org/protobuf v1.31.0 // indirect gopkg.in/alecthomas/kingpin.v2 v2.2.6 // indirect diff --git a/pkg/js/devtools/README.md b/pkg/js/devtools/README.md index 373e4b92ce..65248c2d8a 100644 --- a/pkg/js/devtools/README.md +++ b/pkg/js/devtools/README.md @@ -6,9 +6,6 @@ devtools contains tools and scripts to automate booring tasks related to javascr [bindgen](./bindgen/README.md) is a tool that automatically generated bindings for native go packages with 'goja' -### jsdocgen - -[jsdocgen](./jsdocgen/README.md) is LLM (OpenAI) based dev tool it takes generated javascript files and annotes them with jsdoc comments using predefined prompt ### scrapefuncs diff --git a/pkg/js/devtools/bindgen/cmd/bindgen/main.go b/pkg/js/devtools/bindgen/cmd/bindgen/main.go index 09f493452e..6233f3975a 100644 --- a/pkg/js/devtools/bindgen/cmd/bindgen/main.go +++ b/pkg/js/devtools/bindgen/cmd/bindgen/main.go @@ -16,14 +16,12 @@ var ( dir string generatedDir string targetModules string - goOnly bool ) func main() { flag.StringVar(&dir, "dir", "libs", "directory to process") flag.StringVar(&generatedDir, "out", "generated", "directory to output generated files") flag.StringVar(&targetModules, "target", "", "target modules to generate") - flag.BoolVar(&goOnly, "go", false, "generate only go files") flag.Parse() log.SetFlags(0) if !fileutil.FolderExists(dir) { @@ -54,12 +52,12 @@ func process() error { } prefixed := "lib" + module - if !goOnly { - err = data.WriteJSTemplate(filepath.Join(generatedDir, "js/"+prefixed), module) - if err != nil { - return fmt.Errorf("could not write js template: %v", err) - } - } + // if !goOnly { + // err = data.WriteJSTemplate(filepath.Join(generatedDir, "js/"+prefixed), module) + // if err != nil { + // return fmt.Errorf("could not write js template: %v", err) + // } + // } err = data.WriteGoTemplate(path.Join(generatedDir, "go/"+prefixed), module) if err != nil { return fmt.Errorf("could not write go template: %v", err) diff --git a/pkg/js/devtools/bindgen/generator.go b/pkg/js/devtools/bindgen/generator.go index 5656e419ac..313c6d41ca 100644 --- a/pkg/js/devtools/bindgen/generator.go +++ b/pkg/js/devtools/bindgen/generator.go @@ -28,16 +28,18 @@ var ( // TemplateData contains the parameters for the JS code generator type TemplateData struct { - PackageName string - PackagePath string - PackageFuncs map[string]string - PackageInterfaces map[string]string - PackageFuncsExtraNoType map[string]PackageFunctionExtra - PackageFuncsExtra map[string]PackageFuncExtra - PackageVars map[string]string - PackageVarsValues map[string]string - PackageTypes map[string]string - PackageTypesExtra map[string]PackageTypeExtra + PackageName string + PackagePath string + HasObjects bool + PackageFuncs map[string]string + PackageInterfaces map[string]string + PackageFuncsExtraNoType map[string]PackageFunctionExtra + PackageFuncsExtra map[string]PackageFuncExtra + PackageVars map[string]string + PackageVarsValues map[string]string + PackageTypes map[string]string + PackageTypesExtra map[string]PackageTypeExtra + PackageDefinedConstructor map[string]struct{} typesPackage *types.Package @@ -68,16 +70,17 @@ type PackageFunctionExtra struct { // newTemplateData creates a new template data structure func newTemplateData(packagePrefix, pkgName string) *TemplateData { return &TemplateData{ - PackageName: pkgName, - PackagePath: packagePrefix + pkgName, - PackageFuncs: make(map[string]string), - PackageFuncsExtraNoType: make(map[string]PackageFunctionExtra), - PackageFuncsExtra: make(map[string]PackageFuncExtra), - PackageVars: make(map[string]string), - PackageVarsValues: make(map[string]string), - PackageTypes: make(map[string]string), - PackageInterfaces: make(map[string]string), - PackageTypesExtra: make(map[string]PackageTypeExtra), + PackageName: pkgName, + PackagePath: packagePrefix + pkgName, + PackageFuncs: make(map[string]string), + PackageFuncsExtraNoType: make(map[string]PackageFunctionExtra), + PackageFuncsExtra: make(map[string]PackageFuncExtra), + PackageVars: make(map[string]string), + PackageVarsValues: make(map[string]string), + PackageTypes: make(map[string]string), + PackageInterfaces: make(map[string]string), + PackageTypesExtra: make(map[string]PackageTypeExtra), + PackageDefinedConstructor: make(map[string]struct{}), } } @@ -144,6 +147,24 @@ func CreateTemplateData(directory string, packagePrefix string) (*TemplateData, delete(data.PackageFuncsExtra, item) } } + + // map types with corresponding constructors + for constructor := range data.PackageDefinedConstructor { + object: + for k := range data.PackageTypes { + if strings.Contains(constructor, k) { + data.PackageTypes[k] = constructor + break object + } + } + } + for k, v := range data.PackageTypes { + if k == v || v == "" { + data.HasObjects = true + data.PackageTypes[k] = "" + } + } + return data, nil } @@ -399,11 +420,21 @@ func (d *TemplateData) collectFuncDecl(decl *ast.FuncDecl) (extra PackageFunctio extra.Name = decl.Name.Name extra.Doc = convertCommentsToJavascript(decl.Doc.Text()) + isConstructor := false + for _, arg := range decl.Type.Params.List { + p := exprToString(arg.Type) + if strings.Contains(p, "goja.ConstructorCall") { + isConstructor = true + } for _, name := range arg.Names { extra.Args = append(extra.Args, name.Name) } } + if isConstructor { + d.PackageDefinedConstructor[decl.Name.Name] = struct{}{} + } + extra.Returns = d.extractReturns(decl) return extra } @@ -413,3 +444,22 @@ func convertCommentsToJavascript(comments string) string { suffix := strings.Trim(strings.TrimSuffix(strings.ReplaceAll(comments, "\n", "\n// "), "// "), "\n") return fmt.Sprintf("// %s", suffix) } + +// exprToString converts an expression to a string +func exprToString(expr ast.Expr) string { + switch t := expr.(type) { + case *ast.Ident: + return t.Name + case *ast.SelectorExpr: + return exprToString(t.X) + "." + t.Sel.Name + case *ast.StarExpr: + return exprToString(t.X) + case *ast.ArrayType: + return "[]" + exprToString(t.Elt) + case *ast.InterfaceType: + return "interface{}" + // Add more cases to handle other types + default: + return fmt.Sprintf("%T", expr) + } +} diff --git a/pkg/js/devtools/bindgen/templates/go_class.tmpl b/pkg/js/devtools/bindgen/templates/go_class.tmpl index 74d52b3e02..ede5404719 100644 --- a/pkg/js/devtools/bindgen/templates/go_class.tmpl +++ b/pkg/js/devtools/bindgen/templates/go_class.tmpl @@ -27,18 +27,15 @@ func init() { "{{$objName}}": {{$pkgName}}.{{$objDefine}}, {{- end}} - // Types (value type) + // Objects / Classes {{- range $objName, $objDefine := .PackageTypes}} - "{{$objName}}": {{printf "func() %s.%s { return %s.%s{} }" $pkgName $objDefine $pkgName $objDefine}}, + {{- if $objDefine}} + "{{$objName}}": {{$pkgName}}.{{$objDefine}}, + {{- else}} + "{{$objName}}": gojs.GetClassConstructor[{{$pkgName}}.{{$objName}}](&{{$pkgName}}.{{$objName}}{}), + {{- end}} {{- end}} - // Types (pointer type) - {{range $objName, $objDefine := .PackageTypes}} - {{- $newObjName := printf "%s%s" "New" $objName -}} - {{- if not (exist $pkgFuncs $newObjName) -}} - "{{$newObjName}}": {{printf "func() *%s.%s { return &%s.%s{} }" $pkgName $objDefine $pkgName $objDefine}}, - {{end -}} - {{- end -}} }, ).Register() } diff --git a/pkg/js/devtools/jsdocgen/README.md b/pkg/js/devtools/jsdocgen/README.md deleted file mode 100644 index 10bf824173..0000000000 --- a/pkg/js/devtools/jsdocgen/README.md +++ /dev/null @@ -1,116 +0,0 @@ -## jsdocgen - -jsdocgen is LLM (OpenAI) based dev tool it takes generated javascript files and annotes them with jsdoc comments using predefined prompt - -### Usage - -```bash - ./jsdocgen -h -Usage of ./jsdocgen: - -dir string - directory to process - -key string - openai api key - -keyfile string - openai api key file -``` - -### Example - -```bash -./jsdocgen -dir modules/generated/js/libmysql -keyfile ~/.openai/key -``` - - -### Example Conversion - -when `bindgen` is executed it generates basic javascript (which currently is incorrect) and looks like this but the idea is to generate bare minimum that LLM has idea what we are trying to do - -```javascript -/**@module rdp */ -// rdp implements bindings for rdp protocol in javascript -// to be used from nuclei scanner. - -// RDPClient is a client for rdp servers -class RDPClient { - // CheckRDPAuth checks if the given host and port are running rdp server - // with authentication and returns their metadata. - CheckRDPAuth(host, port) { - return CheckRDPAuthResponse, error; - }; - // IsRDP checks if the given host and port are running rdp server. - // - // If connection is successful, it returns true. - // If connection is unsuccessful, it returns false and error. - // - // The Name of the OS is also returned if the connection is successful. - IsRDP(host, port) { - return IsRDPResponse, error; - }; -}; - - -module.exports = { - RDPClient: RDPClient, -}; -``` - -And when `jsdocgen` is executed it generates the following output - -```javascript -/** - * @module rdp - * This module implements bindings for rdp protocol in javascript to be used from nuclei scanner. - */ - -/** - * @class - * @classdesc RDPClient is a client for rdp servers - */ -class RDPClient { - /** - * @method - * @name CheckRDPAuth - * @description checks if the given host and port are running rdp server with authentication and returns their metadata. - * @param {string} host - The host of the rdp server - * @param {number} port - The port of the rdp server - * @returns {CheckRDPAuthResponse} - The response from the rdp server - * @throws {error} If there is an error in the request - * @example - * let client = new RDPClient(); - * client.CheckRDPAuth("localhost", 3389); - */ - CheckRDPAuth(host, port) { - // implemented in go - }; - - /** - * @method - * @name IsRDP - * @description checks if the given host and port are running rdp server. - * If connection is successful, it returns true. - * If connection is unsuccessful, it throws an error. - * The Name of the OS is also returned if the connection is successful. - * @param {string} host - The host of the rdp server - * @param {number} port - The port of the rdp server - * @returns {IsRDPResponse} - The response from the rdp server - * @throws {error} If there is an error in the request - * @example - * let client = new RDPClient(); - * client.IsRDP("localhost", 3389); - */ - IsRDP(host, port) { - // implemented in go - }; -}; - -module.exports = { - RDPClient: RDPClient, -}; -``` - -Now we can see the output is much more readable and make sense. - -## Note: - -jsdocgen is not perfect and it is not supposed to be, it is intended to **almost** automate boooring stuff but will always require some manual intervention to make it perfect. \ No newline at end of file diff --git a/pkg/js/devtools/jsdocgen/main.go b/pkg/js/devtools/jsdocgen/main.go deleted file mode 100644 index 124b1fd69c..0000000000 --- a/pkg/js/devtools/jsdocgen/main.go +++ /dev/null @@ -1,178 +0,0 @@ -package main - -import ( - "context" - "flag" - "log" - "os" - "path/filepath" - "strings" - - errorutil "github.com/projectdiscovery/utils/errors" - fileutil "github.com/projectdiscovery/utils/file" - openai "github.com/sashabaranov/go-openai" -) - -var ( - dir string - key string - keyfile string -) - -const sysPrompt = ` -you are helpful coding assistant responsible for generating javascript file with js annotations for nuclei from a 'corrupted' javascript file. ---- example input --- -/** @module mymodule */ - -class TestClass { - function Execute(path){ - return []string , error - } -} - -function ListTests(){ - return Testcases , error -} - -module.exports = { - TestClass: TestClass, - ListTests: ListTests, -} ---- end example --- ---- example output --- -/** @module mymodule */ - -/** - * @class - * @classdesc TestClass is a class used for testing purposes - */ -class TestClass { - /** - @method - @description Execute executes the test and returns the results - @param {string} path - The path to execute the test on. - @returns {string[]} - The results of the test in an array. - @throws {error} - The error encountered during test execution. - @example - let m = require('nuclei/mymodule'); - let c = m.TestClass(); - let results = c.Execute('/tmp'); - */ - function Execute(path){ - // implemented in go - }; -}; - -/** - * @typdef {object} Testcases - * @description Testcases is a object containing all the tests. - */ - const Testcases = {}; - - - -/** - * @function - * @description ListTests lists all the tests available - * @returns {Testcases} - The testcases object containing all the tests. - * @throws {error} - The error encountered during test listing. - * @example - * let m = require('nuclei/mymodule'); - * let tests = m.ListTests(); - */ -function ListTests(){ - // implemented in go -}; - -module.exports = { - TestClass: TestClass, - ListTests: ListTests, -} ---- end example --- ---- instructions --- -1. DONOT ADD ANY NEW Annotation (@) Other than those already mentioned in above example -2. All Function/Class/Method body should be empty with comment 'implemented in go' -3. ALL MODULE IMPORT PATHS SHOULD BE 'nuclei/' -4. ALWAYS replace '[]byte' with Uint8Array and treat as equivalent -5. IF AND ONLY IF a function returns unknown objects (ex: LDAPResponse etc) only then create a @typedef and its respecitve declaration using const = {} -6. DONOT create a typedef for built in and known types like string,int,float,[]byte,bool etc -7. JsDOC comments **must** always start with /** and end with */ and each line should start with * (star) ---- end instructions --- -` - -const userPrompt = ` ----original javascript--- -{{source}} ----new javascript--- -` - -// doclint is automatic javascript documentation linter for nuclei -// it uses LLM to autocomplete the generated js code to proper JSDOC notation -func main() { - flag.StringVar(&dir, "dir", "", "directory to process") - flag.StringVar(&key, "key", "", "openai api key") - flag.StringVar(&keyfile, "keyfile", "", "openai api key file") - flag.Parse() - log.SetFlags(0) - - if dir == "" { - log.Fatal("dir is not set") - } - finalKey := "" - if key != "" { - key = finalKey - } - if keyfile != "" && fileutil.FileExists(keyfile) { - data, err := os.ReadFile(keyfile) - if err != nil { - log.Fatal(err) - } - finalKey = string(data) - } - if key := os.Getenv("OPENAI_API_KEY"); key != "" { - finalKey = key - } - - if finalKey == "" { - log.Fatal("openai api key is not set") - } - llm := openai.NewClient(finalKey) - - _ = filepath.WalkDir(dir, func(path string, d os.DirEntry, err error) error { - if !d.IsDir() && filepath.Ext(path) == ".js" { - log.Printf("Processing %s", path) - if err := updateDocsWithLLM(llm, path); err != nil { - log.Printf("Error processing %s: %s", path, err) - } else { - log.Printf("Processed %s", path) - } - } - return nil - }) -} - -// updateDocsWithLLM updates the documentation of a javascript file -func updateDocsWithLLM(llm *openai.Client, path string) error { - // read the file - bin, err := os.ReadFile(path) - if err != nil { - return err - } - - resp, err := llm.CreateChatCompletion(context.TODO(), openai.ChatCompletionRequest{ - Model: "gpt-4", - Messages: []openai.ChatCompletionMessage{ - {Role: "system", Content: sysPrompt}, - {Role: "user", Content: strings.ReplaceAll(userPrompt, "{{source}}", string(bin))}, - }, - Temperature: 0.1, - }) - if err != nil { - return err - } - if len(resp.Choices) == 0 { - return errorutil.New("no choices returned") - } - data := resp.Choices[0].Message.Content - return os.WriteFile(path, []byte(data), 0644) -} diff --git a/pkg/js/devtools/tsgen/README.md b/pkg/js/devtools/tsgen/README.md new file mode 100644 index 0000000000..fe404913c5 --- /dev/null +++ b/pkg/js/devtools/tsgen/README.md @@ -0,0 +1,3 @@ +# tsgen + +tsgen is devtool to generate dummy typescript code for goja node modules written in golang. These generated typescript code can be compiled to generate .d.ts files to provide intellisense to editors like vscode and documentation for the node modules. \ No newline at end of file diff --git a/pkg/js/devtools/tsgen/astutil.go b/pkg/js/devtools/tsgen/astutil.go new file mode 100644 index 0000000000..72e7b1bc8b --- /dev/null +++ b/pkg/js/devtools/tsgen/astutil.go @@ -0,0 +1,109 @@ +package tsgen + +import ( + "fmt" + "go/ast" + "strings" +) + +// isExported checks if the given name is exported +func isExported(name string) bool { + return ast.IsExported(name) +} + +// exprToString converts an expression to a string +func exprToString(expr ast.Expr) string { + switch t := expr.(type) { + case *ast.Ident: + return toTsTypes(t.Name) + case *ast.SelectorExpr: + return exprToString(t.X) + "." + t.Sel.Name + case *ast.StarExpr: + return exprToString(t.X) + case *ast.ArrayType: + return toTsTypes("[]" + exprToString(t.Elt)) + case *ast.InterfaceType: + return "interface{}" + case *ast.MapType: + return "Record<" + toTsTypes(exprToString(t.Key)) + ", " + toTsTypes(exprToString(t.Value)) + ">" + // Add more cases to handle other types + default: + return fmt.Sprintf("%T", expr) + } +} + +// toTsTypes converts Go types to TypeScript types +func toTsTypes(t string) string { + if strings.Contains(t, "interface{}") { + return "any" + } + if strings.HasPrefix(t, "map[") { + return convertMaptoRecord(t) + } + switch t { + case "string": + return "string" + case "int", "int8", "int16", "int32", "int64", "uint", "uint8", "uint16", "uint32", "uint64": + return "number" + case "float32", "float64": + return "number" + case "bool": + return "boolean" + case "[]byte": + return "Uint8Array" + case "interface{}": + return "any" + case "time.Duration": + return "number" + case "time.Time": + return "Date" + default: + if strings.HasPrefix(t, "[]") { + return toTsTypes(strings.TrimPrefix(t, "[]")) + "[]" + } + return t + } +} + +func TsDefaultValue(t string) string { + switch t { + case "string": + return `""` + case "number": + return `0` + case "boolean": + return `false` + case "Uint8Array": + return `new Uint8Array(8)` + case "any": + return `undefined` + case "interface{}": + return `undefined` + default: + if strings.Contains(t, "[]") { + return `[]` + } + return "new " + t + "()" + } +} + +// Ternary is a ternary operator for strings +func Ternary(condition bool, trueVal, falseVal string) string { + if condition { + return trueVal + } + return falseVal +} + +// checkCanFail checks if a function can fail +func checkCanFail(fn *ast.FuncDecl) bool { + if fn.Type.Results != nil { + for _, result := range fn.Type.Results.List { + // Check if any of the return types is an error + if ident, ok := result.Type.(*ast.Ident); ok && ident.Name == "error" { + return true + } + } + } + return false +} diff --git a/pkg/js/devtools/tsgen/cmd/tsgen/main.go b/pkg/js/devtools/tsgen/cmd/tsgen/main.go new file mode 100644 index 0000000000..5296c11933 --- /dev/null +++ b/pkg/js/devtools/tsgen/cmd/tsgen/main.go @@ -0,0 +1,118 @@ +package main + +import ( + "bytes" + _ "embed" + "flag" + "fmt" + "os" + "path/filepath" + "sort" + "strings" + "text/template" + + "github.com/projectdiscovery/gologger" + "github.com/projectdiscovery/nuclei/v3/pkg/js/devtools/tsgen" + fileutil "github.com/projectdiscovery/utils/file" +) + +// Define your template +// +//go:embed tsmodule.go.tmpl +var tsTemplate string + +var ( + source string + out string +) + +func main() { + flag.StringVar(&source, "dir", "", "Directory to parse") + flag.StringVar(&out, "out", "src", "Typescript files Output directory") + flag.Parse() + + // Create an instance of the template + tmpl := template.New("ts") + tmpl = tmpl.Funcs(template.FuncMap{ + "splitLines": func(s string) []string { + tmp := strings.Split(s, "\n") + filtered := []string{} + for _, line := range tmp { + if strings.TrimSpace(line) != "" { + filtered = append(filtered, line) + } + } + return filtered + }, + }) + var err error + tmpl, err = tmpl.Parse(tsTemplate) + if err != nil { + panic(err) + } + + // Create the output directory + _ = fileutil.CreateFolder(out) + + dirs := []string{} + _ = filepath.WalkDir(source, func(path string, d os.DirEntry, err error) error { + if err != nil { + return err + } + // only load module directory skip root directory + if d.IsDir() { + files, _ := os.ReadDir(path) + for _, file := range files { + if !file.IsDir() && strings.HasSuffix(file.Name(), ".go") { + dirs = append(dirs, path) + break + } + } + } + return nil + }) + + // walk each directory + for _, dir := range dirs { + entityList := []tsgen.Entity{} + ep, err := tsgen.NewEntityParser(dir) + if err != nil { + panic(fmt.Errorf("could not create entity parser: %s", err)) + } + if err := ep.Parse(); err != nil { + panic(fmt.Errorf("could not parse entities: %s", err)) + } + entityList = append(entityList, ep.GetEntities()...) + entityList = sortEntities(entityList) + var buff bytes.Buffer + err = tmpl.Execute(&buff, entityList) + if err != nil { + panic(err) + } + moduleName := filepath.Base(dir) + gologger.Info().Msgf("Writing %s.ts", moduleName) + // create appropriate directory if missing + // _ = fileutil.CreateFolder(filepath.Join(out, moduleName)) + _ = os.WriteFile(filepath.Join(out, moduleName)+".ts", buff.Bytes(), 0755) + } + + // generating index.ts file + var buff bytes.Buffer + for _, dir := range dirs { + buff.WriteString(fmt.Sprintf("export * as %s from './%s';\n", filepath.Base(dir), filepath.Base(dir))) + } + _ = os.WriteFile(filepath.Join(out, "index.ts"), buff.Bytes(), 0755) +} + +func sortEntities(entities []tsgen.Entity) []tsgen.Entity { + sort.Slice(entities, func(i, j int) bool { + if entities[i].Type != entities[j].Type { + // Define the order of types + order := map[string]int{"function": 1, "class": 2, "interface": 3} + return order[entities[i].Type] < order[entities[j].Type] + } + // If types are the same, sort by name + return entities[i].Name < entities[j].Name + }) + return entities +} diff --git a/pkg/js/devtools/tsgen/cmd/tsgen/tsmodule.go.tmpl b/pkg/js/devtools/tsgen/cmd/tsgen/tsmodule.go.tmpl new file mode 100644 index 0000000000..ff223e65bb --- /dev/null +++ b/pkg/js/devtools/tsgen/cmd/tsgen/tsmodule.go.tmpl @@ -0,0 +1,79 @@ +{{- range .}} + +{{ if eq .Type "const" -}} +{{ if .Description }}/** {{ .Description }} */{{- end }} +export const {{ .Name }} = {{ .Value }}; +{{- else if eq .Type "class" -}} +/** +{{- range (splitLines .Description) }} + * {{ . }} +{{- end }} + */ +export class {{ .Name }} { + {{"\n"}} + {{- range $property := .Class.Properties }} + {{ if .Description }} + /** + {{- range (splitLines $property.Description) }} + * {{ . }} + {{- end }} + */ + {{ end }} + public {{ $property.Name }}?: {{ $property.Type }}; + {{"\n"}} + {{- end }} + // Constructor of {{ .Name}} + {{- if eq (len .Class.Constructor.Parameters) 0 }} + constructor() {} + {{- else }} + constructor( + {{- range $index, $param := .Class.Constructor.Parameters }} + {{- if $index }}, {{ end }}{{ $param.Name }}: {{ $param.Type }} + {{- end }} ) {} + {{"\n"}} + {{- end }} + + {{- range $method := .Class.Methods }} + /** + {{- range (splitLines $method.Description) }} + * {{ . }} + {{- end }} + */ + public {{ $method.Name }}({{ range $index, $element := $method.Parameters }}{{ if $index }}, {{ end }}{{ $element.Name }}: {{ $element.Type }}{{ end }}): {{ $method.Returns }} { + {{ $method.ReturnStmt }} + } + {{"\n"}} + {{- end }} +} + +{{ else if eq .Type "function" -}} +/** +{{- range (splitLines .Description) }} + * {{ . }} +{{- end }} + */ +export function {{ .Name }}({{ range $index, $element := .Function.Parameters }}{{ if $index }}, {{ end }}{{ $element.Name }}: {{ $element.Type }}{{ end }}): {{ .Function.Returns }} { + {{ .Function.ReturnStmt }} +} + +{{ else if eq .Type "interface" -}} +/** +{{- range (splitLines .Description) }} + * {{ . }} +{{- end }} + */ +export interface {{ .Name }} { + {{- range $property := .Object.Properties }} + {{ if .Description }} + /** + {{- range (splitLines .Description) }} + * {{ . }} + {{- end }} + */ + {{ end }} + {{ $property.Name }}?: {{ $property.Type }}, + {{- end }} +} + +{{ end }} +{{- end }} \ No newline at end of file diff --git a/pkg/js/devtools/tsgen/parser.go b/pkg/js/devtools/tsgen/parser.go new file mode 100644 index 0000000000..e285b5f007 --- /dev/null +++ b/pkg/js/devtools/tsgen/parser.go @@ -0,0 +1,585 @@ +package tsgen + +import ( + "errors" + "fmt" + "go/ast" + "go/parser" + "go/token" + "regexp" + "strings" + + "github.com/projectdiscovery/gologger" + sliceutil "github.com/projectdiscovery/utils/slice" + "golang.org/x/tools/go/packages" +) + +// EntityParser is responsible for parsing a go file and generating +// corresponding typescript entities. +type EntityParser struct { + syntax []*ast.File + structTypes map[string]Entity + imports map[string]*packages.Package + newObjects map[string]*Entity // new objects to create from external packages + vars []Entity + entities []Entity +} + +// NewEntityParser creates a new EntityParser +func NewEntityParser(dir string) (*EntityParser, error) { + + cfg := &packages.Config{ + Mode: packages.NeedName | packages.NeedFiles | packages.NeedImports | + packages.NeedTypes | packages.NeedSyntax | packages.NeedTypes | + packages.NeedModule | packages.NeedTypesInfo, + Tests: false, + Dir: dir, + ParseFile: func(fset *token.FileSet, filename string, src []byte) (*ast.File, error) { + return parser.ParseFile(fset, filename, src, parser.ParseComments) + }, + } + pkgs, err := packages.Load(cfg, ".") + if err != nil { + return nil, err + } + if len(pkgs) == 0 { + return nil, errors.New("no packages found") + } + pkg := pkgs[0] + + return &EntityParser{ + syntax: pkg.Syntax, + structTypes: map[string]Entity{}, + imports: map[string]*packages.Package{}, + newObjects: map[string]*Entity{}, + }, nil +} + +func (p *EntityParser) GetEntities() []Entity { + return p.entities +} + +// Parse parses the given file and generates corresponding typescript entities +func (p *EntityParser) Parse() error { + p.extractVarsNConstants() + // extract all struct types from the AST + p.extractStructTypes() + // load all imported packages + if err := p.loadImportedPackages(); err != nil { + return err + } + + for _, file := range p.syntax { + // Traverse the AST and find all relevant declarations + ast.Inspect(file, func(n ast.Node) bool { + // look for funtions and methods + // and generate entities for them + fn, ok := n.(*ast.FuncDecl) + if ok { + if !isExported(fn.Name.Name) { + return false + } + entity, err := p.extractFunctionFromNode(fn) + if err != nil { + gologger.Error().Msgf("Could not extract function %s: %s\n", fn.Name.Name, err) + return false + } + + if entity.IsConstructor { + // add this to the list of entities + p.entities = append(p.entities, entity) + return false + } + + // check if function has a receiver + if fn.Recv != nil { + // get the name of the receiver + receiverName := exprToString(fn.Recv.List[0].Type) + // check if the receiver is a struct + if _, ok := p.structTypes[receiverName]; ok { + // add the method to the class + method := Method{ + Name: entity.Name, + Description: strings.ReplaceAll(entity.Description, "Function", "Method"), + Parameters: entity.Function.Parameters, + Returns: entity.Function.Returns, + CanFail: entity.Function.CanFail, + ReturnStmt: entity.Function.ReturnStmt, + } + + // add this method to corresponding class + allMethods := p.structTypes[receiverName].Class.Methods + if allMethods == nil { + allMethods = []Method{} + } + entity = p.structTypes[receiverName] + entity.Class.Methods = append(allMethods, method) + p.structTypes[receiverName] = entity + return false + } + } + // add the function to the list of global entities + p.entities = append(p.entities, entity) + return false + } + + return true + }) + } + + for _, file := range p.syntax { + ast.Inspect(file, func(n ast.Node) bool { + // logic here to extract all fields and methods from a struct + // and add them to the entities slice + // TODO: we only support structs and not type aliases + typeSpec, ok := n.(*ast.TypeSpec) + if ok { + if !isExported(typeSpec.Name.Name) { + return false + } + structType, ok := typeSpec.Type.(*ast.StructType) + if !ok { + // This is not a struct, so continue traversing the AST + return false + } + entity := Entity{ + Name: typeSpec.Name.Name, + Type: "class", + Description: Ternary(strings.TrimSpace(typeSpec.Doc.Text()) != "", typeSpec.Doc.Text(), typeSpec.Name.Name+" Class"), + Class: Class{ + Properties: p.extractClassProperties(structType), + }, + } + // map struct name to entity and create a new entity if doesn't exist + if _, ok := p.structTypes[typeSpec.Name.Name]; ok { + entity.Class.Methods = p.structTypes[typeSpec.Name.Name].Class.Methods + entity.Description = p.structTypes[typeSpec.Name.Name].Description + p.structTypes[typeSpec.Name.Name] = entity + } else { + p.structTypes[typeSpec.Name.Name] = entity + } + return false + } + // Continue traversing the AST + return true + }) + } + + // add all struct types to the list of global entities + for k, v := range p.structTypes { + if v.Type == "class" && len(v.Class.Methods) > 0 { + p.entities = append(p.entities, v) + } else if v.Type == "class" && len(v.Class.Methods) == 0 { + if k == "Object" { + continue + } + entity := Entity{ + Name: k, + Type: "interface", + Description: strings.TrimSpace(strings.ReplaceAll(v.Description, "Class", "interface")), + Object: Interface{ + Properties: v.Class.Properties, + }, + } + p.entities = append(p.entities, entity) + } + } + + // handle external structs + for k := range p.newObjects { + // if k == "Object" { + // continue + // } + if err := p.scrapeAndCreate(k); err != nil { + return fmt.Errorf("could not scrape and create new object: %s", err) + } + } + + interfaceList := map[string]struct{}{} + for _, v := range p.entities { + if v.Type == "interface" { + interfaceList[v.Name] = struct{}{} + } + } + + // handle method return types + for index, v := range p.entities { + if len(v.Class.Methods) > 0 { + for i, method := range v.Class.Methods { + if !strings.Contains(method.Returns, "null") { + x := strings.TrimSpace(method.Returns) + if _, ok := interfaceList[x]; ok { + // non nullable interface return type detected + method.Returns = x + " | null" + method.ReturnStmt = "return null;" + p.entities[index].Class.Methods[i] = method + } + } + } + } + } + + // handle constructors + for _, v := range p.entities { + if v.IsConstructor { + + // correlate it with the class + foundStruct: + for i, class := range p.entities { + if class.Type != "class" { + continue foundStruct + } + if strings.Contains(v.Name, class.Name) { + // add constructor to the class + p.entities[i].Class.Constructor = v.Function + break foundStruct + } + } + } + } + + filtered := []Entity{} + for _, v := range p.entities { + if !v.IsConstructor { + filtered = append(filtered, v) + } + } + + // add all vars and constants + filtered = append(filtered, p.vars...) + + p.entities = filtered + return nil +} + +// extractPropertiesFromStruct extracts all properties from the given struct +func (p *EntityParser) extractClassProperties(node *ast.StructType) []Property { + var properties []Property + + for _, field := range node.Fields.List { + // Skip unexported fields + if len(field.Names) > 0 && !field.Names[0].IsExported() { + continue + } + + // Get the type of the field as a string + typeString := exprToString(field.Type) + + // If the field is anonymous (embedded), use the type name as the field name + if len(field.Names) == 0 { + if ident, ok := field.Type.(*ast.Ident); ok { + properties = append(properties, Property{ + Name: ident.Name, + Type: typeString, + Description: field.Doc.Text(), + }) + } + continue + } + + // Iterate through all names (for multiple names in a single declaration) + for _, fieldName := range field.Names { + // Only consider exported fields + if fieldName.IsExported() { + property := Property{ + Name: fieldName.Name, + Type: typeString, + Description: field.Doc.Text(), + } + if strings.Contains(property.Type, ".") { + // external struct found + property.Type = p.handleExternalStruct(property.Type) + } + properties = append(properties, property) + } + } + } + return properties +} + +var ( + constructorRe = `(constructor\([^)]*\))` + constructorReCompiled = regexp.MustCompile(constructorRe) +) + +// extractFunctionFromNode extracts a function from the given AST node +func (p *EntityParser) extractFunctionFromNode(fn *ast.FuncDecl) (Entity, error) { + entity := Entity{ + Name: fn.Name.Name, + Type: "function", + Description: Ternary(strings.TrimSpace(fn.Doc.Text()) != "", fn.Doc.Text(), fn.Name.Name+" Function"), + Function: Function{ + Parameters: p.extractParameters(fn), + Returns: p.extractReturnType(fn), + CanFail: checkCanFail(fn), + }, + } + // check if it is a constructor + if strings.Contains(entity.Function.Returns, "Object") && len(entity.Function.Parameters) == 2 { + // this is a constructor defined that accepts something as input + // get constructor signature from comments + constructorSig := constructorReCompiled.FindString(entity.Description) + entity.IsConstructor = true + entity.Function = updateFuncWithConstructorSig(constructorSig, entity.Function) + return entity, nil + } + + // fix/adjust return statement + if entity.Function.Returns == "void" { + entity.Function.ReturnStmt = "return;" + } else if strings.Contains(entity.Function.Returns, "null") { + entity.Function.ReturnStmt = "return null;" + } else if fn.Recv != nil && exprToString(fn.Recv.List[0].Type) == entity.Function.Returns { + entity.Function.ReturnStmt = "return this;" + } else { + entity.Function.ReturnStmt = "return " + TsDefaultValue(entity.Function.Returns) + ";" + } + return entity, nil +} + +// extractReturnType extracts the return type from the given function +func (p *EntityParser) extractReturnType(fn *ast.FuncDecl) (out string) { + defer func() { + if out == "" { + out = "void" + } + if strings.Contains(out, "interface{}") { + out = strings.ReplaceAll(out, "interface{}", "any") + } + }() + var returns []string + if fn.Type.Results != nil && len(fn.Type.Results.List) > 0 { + for _, result := range fn.Type.Results.List { + tmp := exprToString(result.Type) + if strings.Contains(tmp, ".") && !strings.HasPrefix(tmp, "goja.") { + tmp = p.handleExternalStruct(tmp) + " | null" // external object interfaces can always return null + } + returns = append(returns, tmp) + } + } + if len(returns) == 1 { + val := returns[0] + val = strings.TrimPrefix(val, "*") + if val == "error" { + out = "void" + } else { + out = val + } + return + } + if len(returns) > 1 { + // in goja we stick 2 only 2 values with one being error + for _, val := range returns { + val = strings.TrimPrefix(val, "*") + if val != "error" { + out = val + break + } + } + if sliceutil.Contains(returns, "error") { + // add | null to the return type + out = out + " | null" + return + } + } + return "void" +} + +// example: Map[string][]string -> Record +func convertMaptoRecord(input string) (out string) { + var key, value string + input = strings.TrimPrefix(input, "Map[") + key = input[:strings.Index(input, "]")] + value = input[strings.Index(input, "]")+1:] + return "Record<" + toTsTypes(key) + ", " + toTsTypes(value) + ">" +} + +// extractParameters extracts all parameters from the given function +func (p *EntityParser) extractParameters(fn *ast.FuncDecl) []Parameter { + var parameters []Parameter + for _, param := range fn.Type.Params.List { + // get the parameter name + name := param.Names[0].Name + // get the parameter type + typ := exprToString(param.Type) + if strings.Contains(typ, ".") { + // replace with any + // we do not support or encourage passing external structs as parameters + typ = "any" + } + // add the parameter to the list of parameters + parameters = append(parameters, Parameter{ + Name: name, + Type: toTsTypes(typ), + }) + } + return parameters +} + +// typeName is in format ssh.ClientConfig +// it first fetches all fields from the struct and creates a new object +// with that name and returns name of that object as type +func (p *EntityParser) handleExternalStruct(typeName string) string { + baseType := typeName[strings.LastIndex(typeName, ".")+1:] + p.newObjects[typeName] = &Entity{ + Name: baseType, + Type: "interface", + Description: baseType + " Object", + } + // @tarunKoyalwar: scrape and create new object + // pkg := pkgMap[strings.Split(tmp, ".")[0]] + // if pkg == nil { + // for k := range pkgMap { + // fmt.Println(k) + // } + // panic("package not found") + // } + // props, err := extractFieldsFromType(pkg, tmp[strings.LastIndex(tmp, ".")+1:]) + // if err != nil { + // panic(err) + // } + // // newObject := Entity{ + // // Name: tmp[strings.LastIndex(tmp, ".")+1:], + // // Type: "interface", + // // Object: Object{ + // // Properties: props, + // // }, + // // } + // fmt.Println(props) + return baseType +} + +// extractStructTypes extracts all struct types from the AST +func (p *EntityParser) extractStructTypes() { + for _, file := range p.syntax { + ast.Inspect(file, func(n ast.Node) bool { + // Check if the node is a type specification (which includes structs) + typeSpec, ok := n.(*ast.TypeSpec) + if ok { + // Check if the type specification is a struct type + _, ok := typeSpec.Type.(*ast.StructType) + if ok { + // Add the struct name to the list of struct names + p.structTypes[typeSpec.Name.Name] = Entity{ + Name: typeSpec.Name.Name, + Description: typeSpec.Doc.Text(), + } + } + } + // Continue traversing the AST + return true + }) + } + +} + +// extraGlobalConstant and vars +func (p *EntityParser) extractVarsNConstants() { + p.vars = []Entity{} + for _, file := range p.syntax { + ast.Inspect(file, func(n ast.Node) bool { + // Check if the node is a type specification (which includes structs) + gen, ok := n.(*ast.GenDecl) + if !ok { + return true + } + for _, v := range gen.Specs { + switch spec := v.(type) { + case *ast.ValueSpec: + if !spec.Names[0].IsExported() { + continue + } + if spec.Values == nil || len(spec.Values) == 0 { + continue + } + // get comments or description + p.vars = append(p.vars, Entity{ + Name: spec.Names[0].Name, + Type: "const", + Description: strings.TrimSpace(spec.Comment.Text()), + Value: spec.Values[0].(*ast.BasicLit).Value, + }) + } + } + // Continue traversing the AST + return true + }) + } +} + +// loadImportedPackages loads all imported packages +func (p *EntityParser) loadImportedPackages() error { + // get all import statements + // iterate over all imports + for _, file := range p.syntax { + for _, imp := range file.Imports { + // get the package path + path := imp.Path.Value + // remove the quotes from the path + path = path[1 : len(path)-1] + // load the package + pkg, err := loadPackage(path) + if err != nil { + return err + } + importName := path[strings.LastIndex(path, "/")+1:] + if imp.Name != nil { + importName = imp.Name.Name + } else { + if !strings.HasSuffix(imp.Path.Value, pkg.Types.Name()+`"`) { + importName = pkg.Types.Name() + } + } + // add the package to the map + if _, ok := p.imports[importName]; !ok { + p.imports[importName] = pkg + } + } + } + return nil +} + +// Load the package containing the type definition +// TODO: we don't support named imports yet +func loadPackage(pkgPath string) (*packages.Package, error) { + cfg := &packages.Config{Mode: packages.NeedTypes | packages.NeedSyntax | packages.NeedTypesInfo} + pkgs, err := packages.Load(cfg, pkgPath) + if err != nil { + return nil, err + } + if len(pkgs) == 0 { + return nil, errors.New("no packages found") + } + return pkgs[0], nil +} + +// exprToString converts an expression to a string +func updateFuncWithConstructorSig(sig string, f Function) Function { + sig = strings.TrimSpace(sig) + f.Parameters = []Parameter{} + f.CanFail = true + f.ReturnStmt = "" + f.Returns = "" + if sig == "" { + return f + } + // example: constructor(public domain: string, public controller?: string) + // remove constructor( and ) + sig = strings.TrimPrefix(sig, "constructor(") + sig = strings.TrimSuffix(sig, ")") + // split by comma + args := strings.Split(sig, ",") + for _, arg := range args { + arg = strings.TrimSpace(arg) + // check if it is optional + typeData := strings.Split(arg, ":") + if len(typeData) != 2 { + panic("invalid constructor signature") + } + f.Parameters = append(f.Parameters, Parameter{ + Name: strings.TrimSpace(typeData[0]), + Type: strings.TrimSpace(typeData[1]), + }) + } + return f +} diff --git a/pkg/js/devtools/tsgen/scrape.go b/pkg/js/devtools/tsgen/scrape.go new file mode 100644 index 0000000000..960700f579 --- /dev/null +++ b/pkg/js/devtools/tsgen/scrape.go @@ -0,0 +1,192 @@ +package tsgen + +import ( + "fmt" + "go/types" + "regexp" + "strings" + + errorutil "github.com/projectdiscovery/utils/errors" +) + +// scrape.go scrapes all information of exported type from different package + +func (p *EntityParser) scrapeAndCreate(typeName string) error { + if p.newObjects[typeName] == nil { + return nil + } + // get package name + pkgName := strings.Split(typeName, ".")[0] + baseTypeName := strings.Split(typeName, ".")[1] + // get package + pkg, ok := p.imports[pkgName] + if !ok { + return errorutil.New("package %v for type %v not found", pkgName, typeName) + } + // get type + obj := pkg.Types.Scope().Lookup(baseTypeName) + if obj == nil { + return errorutil.New("type %v not found in package %+v", typeName, pkg) + } + // Ensure the object is a type name + typeNameObj, ok := obj.(*types.TypeName) + if !ok { + return errorutil.New("%v is not a type name", typeName) + } + // Ensure the type is a named struct type + namedStruct, ok := typeNameObj.Type().Underlying().(*types.Struct) + if !ok { + return fmt.Errorf("%s is not a named struct type", typeName) + } + // fmt.Printf("got named struct %v\n", namedStruct) + // Iterate over the struct fields + d := &ExtObject{ + builtIn: make(map[string]string), + nested: map[string]map[string]*ExtObject{}, + } + + // fmt.Printf("fields %v\n", namedStruct.NumFields()) + for i := 0; i < namedStruct.NumFields(); i++ { + field := namedStruct.Field(i) + fieldName := field.Name() + if field.Exported() { + recursiveScrapeType(nil, fieldName, field.Type(), d) + } + } + entityMap := make(map[string]Entity) + // convert ExtObject to Entity + properties := ConvertExtObjectToEntities(d, entityMap) + entityMap[baseTypeName] = Entity{ + Name: baseTypeName, + Type: "interface", + Description: fmt.Sprintf("%v Interface", baseTypeName), + Object: Interface{ + Properties: properties, + }, + } + + for _, entity := range entityMap { + p.entities = append(p.entities, entity) + } + + return nil +} + +type ExtObject struct { + builtIn map[string]string + nested map[string]map[string]*ExtObject // Changed to map of field names to ExtObject +} + +func recursiveScrapeType(parentType types.Type, fieldName string, fieldType types.Type, extObject *ExtObject) { + if named, ok := fieldType.(*types.Named); ok && !named.Obj().Exported() { + // fmt.Printf("type %v is not exported\n", named.Obj().Name()) + return + } + + if fieldType.String() == "time.Time" { + extObject.builtIn[fieldName] = "Date" + return + } + + switch t := fieldType.Underlying().(type) { + case *types.Pointer: + // fmt.Printf("type %v is a pointer\n", fieldType) + recursiveScrapeType(nil, fieldName, t.Elem(), extObject) + case *types.Signature: + // fmt.Printf("type %v is a callback or interface\n", fieldType) + case *types.Basic: + // Check for basic types (built-in types) + if parentType != nil { + switch p := parentType.Underlying().(type) { + case *types.Slice: + extObject.builtIn[fieldName] = "[]" + fieldType.String() + case *types.Array: + extObject.builtIn[fieldName] = fmt.Sprintf("[%v]", p.Len()) + fieldType.String() + } + } else { + extObject.builtIn[fieldName] = fieldType.String() + } + case *types.Struct: + // Check for struct types + if extObject.nested[fieldName] == nil { + // @tarunKoyalwar: it currently does not supported struct arrays + extObject.nested[fieldName] = make(map[string]*ExtObject) + } + nestedExtObject := &ExtObject{ + builtIn: make(map[string]string), + nested: map[string]map[string]*ExtObject{}, + } + extObject.nested[fieldName][fieldType.String()] = nestedExtObject + for i := 0; i < t.NumFields(); i++ { + field := t.Field(i) + if field.Exported() { + recursiveScrapeType(nil, field.Name(), field.Type(), nestedExtObject) + } + } + case *types.Array: + // fmt.Printf("type %v is an array\n", fieldType) + // get array type + recursiveScrapeType(t, fieldName, t.Elem(), extObject) + case *types.Slice: + // fmt.Printf("type %v is a slice\n", fieldType) + // get slice type + recursiveScrapeType(t, fieldName, t.Elem(), extObject) + default: + // fmt.Printf("type %v is not a builtIn or struct\n", fieldType) + } +} + +var re = regexp.MustCompile(`\[[0-9]+\].*`) + +// ConvertExtObjectToEntities recursively converts an ExtObject to a list of Entity objects +func ConvertExtObjectToEntities(extObj *ExtObject, nestedTypes map[string]Entity) []Property { + var properties []Property + + // Iterate over the built-in types + for fieldName, fieldType := range extObj.builtIn { + var description string + if re.MatchString(fieldType) { + // if it is a fixed size array add len in description + description = fmt.Sprintf("fixed size array of length: %v", fieldType[:strings.Index(fieldType, "]")+1]) + // remove length from type + fieldType = "[]" + fieldType[strings.Index(fieldType, "]")+1:] + } + if strings.Contains(fieldType, "time.Duration") { + description = "time in nanoseconds" + } + px := Property{ + Name: fieldName, + Type: toTsTypes(fieldType), + Description: description, + } + + if strings.HasPrefix(px.Type, "[") { + px.Type = fieldType[strings.Index(px.Type, "]")+1:] + "[]" + } + properties = append(properties, px) + } + + // Iterate over the nested types + for fieldName, nestedExtObjects := range extObj.nested { + for origType, nestedExtObject := range nestedExtObjects { + // fix:me this nestedExtObject always has only one element + got := ConvertExtObjectToEntities(nestedExtObject, nestedTypes) + baseTypename := origType[strings.LastIndex(origType, ".")+1:] + // create new nestedType + nestedTypes[baseTypename] = Entity{ + Name: baseTypename, + Description: fmt.Sprintf("%v Interface", baseTypename), + Type: "interface", + Object: Interface{ + Properties: got, + }, + } + // assign current field type to nested type + properties = append(properties, Property{ + Name: fieldName, + Type: baseTypename, + }) + } + } + return properties +} diff --git a/pkg/js/devtools/tsgen/types.go b/pkg/js/devtools/tsgen/types.go new file mode 100644 index 0000000000..d7e67e6c8a --- /dev/null +++ b/pkg/js/devtools/tsgen/types.go @@ -0,0 +1,60 @@ +package tsgen + +// Define a struct to hold information about your TypeScript entities +type Entity struct { + Name string + Value string + Type string // "class", "function", or "object" or "interface" or "const" + Description string + Example string // this will be part of description with @example jsdoc tag + Class Class // if Type == "class" + Function Function // if Type == "function" + Object Interface // if Type == "object" + IsConstructor bool // true if this is a constructor function +} + +// Class represents a TypeScript class data structure +type Class struct { + Properties []Property + Methods []Method + Constructor Function +} + +// Function represents a TypeScript function data structure +// If CanFail is true, the function returns a Result type +// So modify the function signature to return a Result type in this case +type Function struct { + Parameters []Parameter + Returns string + CanFail bool + ReturnStmt string +} + +type Interface struct { + Properties []Property +} + +// Method represents a TypeScript method data structure +// If CanFail is true, the method returns a Result type +// So modify the method signature to return a Result type in this case +type Method struct { + Name string + Description string + Parameters []Parameter + Returns string + CanFail bool + ReturnStmt string +} + +// Property represent class or object property +type Property struct { + Name string + Type string + Description string +} + +// Parameter represents function or method parameter +type Parameter struct { + Name string + Type string +} diff --git a/pkg/js/generated/go/libbytes/bytes.go b/pkg/js/generated/go/libbytes/bytes.go index ec521be348..c2955acf42 100644 --- a/pkg/js/generated/go/libbytes/bytes.go +++ b/pkg/js/generated/go/libbytes/bytes.go @@ -19,10 +19,8 @@ func init() { // Var and consts - // Types (value type) - "Buffer": func() lib_bytes.Buffer { return lib_bytes.Buffer{} }, - - // Types (pointer type) + // Objects / Classes + "Buffer": lib_bytes.NewBuffer, }, ).Register() } diff --git a/pkg/js/generated/go/libfs/fs.go b/pkg/js/generated/go/libfs/fs.go index 73056a89b2..bc3e509931 100644 --- a/pkg/js/generated/go/libfs/fs.go +++ b/pkg/js/generated/go/libfs/fs.go @@ -22,9 +22,8 @@ func init() { // Var and consts - // Types (value type) + // Objects / Classes - // Types (pointer type) }, ).Register() } diff --git a/pkg/js/generated/go/libgoconsole/goconsole.go b/pkg/js/generated/go/libgoconsole/goconsole.go index 7b057de3cb..c8056d5051 100644 --- a/pkg/js/generated/go/libgoconsole/goconsole.go +++ b/pkg/js/generated/go/libgoconsole/goconsole.go @@ -19,10 +19,8 @@ func init() { // Var and consts - // Types (value type) - "GoConsolePrinter": func() lib_goconsole.GoConsolePrinter { return lib_goconsole.GoConsolePrinter{} }, - - // Types (pointer type) + // Objects / Classes + "GoConsolePrinter": gojs.GetClassConstructor[lib_goconsole.GoConsolePrinter](&lib_goconsole.GoConsolePrinter{}), }, ).Register() } diff --git a/pkg/js/generated/go/libikev2/ikev2.go b/pkg/js/generated/go/libikev2/ikev2.go index 639f14aa53..9d7e588244 100644 --- a/pkg/js/generated/go/libikev2/ikev2.go +++ b/pkg/js/generated/go/libikev2/ikev2.go @@ -26,15 +26,10 @@ func init() { "IKE_NOTIFY_USE_TRANSPORT_MODE": lib_ikev2.IKE_NOTIFY_USE_TRANSPORT_MODE, "IKE_VERSION_2": lib_ikev2.IKE_VERSION_2, - // Types (value type) - "IKEMessage": func() lib_ikev2.IKEMessage { return lib_ikev2.IKEMessage{} }, - "IKENonce": func() lib_ikev2.IKENonce { return lib_ikev2.IKENonce{} }, - "IKENotification": func() lib_ikev2.IKENotification { return lib_ikev2.IKENotification{} }, - - // Types (pointer type) - "NewIKEMessage": func() *lib_ikev2.IKEMessage { return &lib_ikev2.IKEMessage{} }, - "NewIKENonce": func() *lib_ikev2.IKENonce { return &lib_ikev2.IKENonce{} }, - "NewIKENotification": func() *lib_ikev2.IKENotification { return &lib_ikev2.IKENotification{} }, + // Objects / Classes + "IKEMessage": gojs.GetClassConstructor[lib_ikev2.IKEMessage](&lib_ikev2.IKEMessage{}), + "IKENonce": gojs.GetClassConstructor[lib_ikev2.IKENonce](&lib_ikev2.IKENonce{}), + "IKENotification": gojs.GetClassConstructor[lib_ikev2.IKENotification](&lib_ikev2.IKENotification{}), }, ).Register() } diff --git a/pkg/js/generated/go/libkerberos/kerberos.go b/pkg/js/generated/go/libkerberos/kerberos.go index 2dc2da320b..db367ef562 100644 --- a/pkg/js/generated/go/libkerberos/kerberos.go +++ b/pkg/js/generated/go/libkerberos/kerberos.go @@ -24,16 +24,11 @@ func init() { // Var and consts - // Types (value type) + // Objects / Classes "Client": lib_kerberos.NewKerberosClient, - "EnumerateUserResponse": func() lib_kerberos.EnumerateUserResponse { return lib_kerberos.EnumerateUserResponse{} }, - "TGS": func() lib_kerberos.TGS { return lib_kerberos.TGS{} }, - "Config": func() lib_kerberos.Config { return lib_kerberos.Config{} }, - - // Types (pointer type) - // "NewClient": func() *lib_kerberos.Client { return &lib_kerberos.Client{} }, - // "NewEnumerateUserResponse": func() *lib_kerberos.EnumerateUserResponse { return &lib_kerberos.EnumerateUserResponse{} }, - // "NewTGS": func() *lib_kerberos.TGS { return &lib_kerberos.TGS{} }, + "Config": gojs.GetClassConstructor[lib_kerberos.Config](&lib_kerberos.Config{}), + "EnumerateUserResponse": gojs.GetClassConstructor[lib_kerberos.EnumerateUserResponse](&lib_kerberos.EnumerateUserResponse{}), + "TGS": gojs.GetClassConstructor[lib_kerberos.TGS](&lib_kerberos.TGS{}), }, ).Register() } diff --git a/pkg/js/generated/go/libldap/ldap.go b/pkg/js/generated/go/libldap/ldap.go index 32ac0d4f5b..8d0c2702e4 100644 --- a/pkg/js/generated/go/libldap/ldap.go +++ b/pkg/js/generated/go/libldap/ldap.go @@ -20,6 +20,7 @@ func init() { "DecodeZuluTimestamp": lib_ldap.DecodeZuluTimestamp, "JoinFilters": lib_ldap.JoinFilters, "NegativeFilter": lib_ldap.NegativeFilter, + "NewClient": lib_ldap.NewClient, // Var and consts "FilterAccountDisabled": lib_ldap.FilterAccountDisabled, @@ -51,16 +52,11 @@ func init() { "FilterUseDesKeyOnly": lib_ldap.FilterUseDesKeyOnly, "FilterWorkstationTrustAccount": lib_ldap.FilterWorkstationTrustAccount, - // Types (value type) - "ADObject": func() lib_ldap.ADObject { return lib_ldap.ADObject{} }, + // Objects / Classes + "ADObject": gojs.GetClassConstructor[lib_ldap.ADObject](&lib_ldap.ADObject{}), "Client": lib_ldap.NewClient, - "Config": func() lib_ldap.Config { return lib_ldap.Config{} }, - "Metadata": func() lib_ldap.Metadata { return lib_ldap.Metadata{} }, - - // Types (pointer type) - "NewADObject": func() *lib_ldap.ADObject { return &lib_ldap.ADObject{} }, - "NewConfig": func() *lib_ldap.Config { return &lib_ldap.Config{} }, - "NewMetadata": func() *lib_ldap.Metadata { return &lib_ldap.Metadata{} }, + "Config": gojs.GetClassConstructor[lib_ldap.Config](&lib_ldap.Config{}), + "Metadata": gojs.GetClassConstructor[lib_ldap.Metadata](&lib_ldap.Metadata{}), }, ).Register() } diff --git a/pkg/js/generated/go/libmssql/mssql.go b/pkg/js/generated/go/libmssql/mssql.go index ba2a2c57bf..48edb8352e 100644 --- a/pkg/js/generated/go/libmssql/mssql.go +++ b/pkg/js/generated/go/libmssql/mssql.go @@ -18,11 +18,8 @@ func init() { // Var and consts - // Types (value type) - "MSSQLClient": func() lib_mssql.MSSQLClient { return lib_mssql.MSSQLClient{} }, - - // Types (pointer type) - "NewMSSQLClient": func() *lib_mssql.MSSQLClient { return &lib_mssql.MSSQLClient{} }, + // Objects / Classes + "MSSQLClient": gojs.GetClassConstructor[lib_mssql.MSSQLClient](&lib_mssql.MSSQLClient{}), }, ).Register() } diff --git a/pkg/js/generated/go/libmysql/mysql.go b/pkg/js/generated/go/libmysql/mysql.go index 7c8c760022..1ec1817011 100644 --- a/pkg/js/generated/go/libmysql/mysql.go +++ b/pkg/js/generated/go/libmysql/mysql.go @@ -15,14 +15,14 @@ func init() { module.Set( gojs.Objects{ // Functions + "BuildDSN": lib_mysql.BuildDSN, // Var and consts - // Types (value type) - "MySQLClient": func() lib_mysql.MySQLClient { return lib_mysql.MySQLClient{} }, - - // Types (pointer type) - "NewMySQLClient": func() *lib_mysql.MySQLClient { return &lib_mysql.MySQLClient{} }, + // Objects / Classes + "MySQLClient": gojs.GetClassConstructor[lib_mysql.MySQLClient](&lib_mysql.MySQLClient{}), + "MySQLInfo": gojs.GetClassConstructor[lib_mysql.MySQLInfo](&lib_mysql.MySQLInfo{}), + "MySQLOptions": gojs.GetClassConstructor[lib_mysql.MySQLOptions](&lib_mysql.MySQLOptions{}), }, ).Register() } diff --git a/pkg/js/generated/go/libnet/net.go b/pkg/js/generated/go/libnet/net.go index a41cb99f4d..031bba2ba7 100644 --- a/pkg/js/generated/go/libnet/net.go +++ b/pkg/js/generated/go/libnet/net.go @@ -20,11 +20,8 @@ func init() { // Var and consts - // Types (value type) - "NetConn": func() lib_net.NetConn { return lib_net.NetConn{} }, - - // Types (pointer type) - "NewNetConn": func() *lib_net.NetConn { return &lib_net.NetConn{} }, + // Objects / Classes + "NetConn": gojs.GetClassConstructor[lib_net.NetConn](&lib_net.NetConn{}), }, ).Register() } diff --git a/pkg/js/generated/go/liboracle/oracle.go b/pkg/js/generated/go/liboracle/oracle.go index 5d84d90235..5b4bdd7a1b 100644 --- a/pkg/js/generated/go/liboracle/oracle.go +++ b/pkg/js/generated/go/liboracle/oracle.go @@ -18,13 +18,9 @@ func init() { // Var and consts - // Types (value type) - "IsOracleResponse": func() lib_oracle.IsOracleResponse { return lib_oracle.IsOracleResponse{} }, - "OracleClient": func() lib_oracle.OracleClient { return lib_oracle.OracleClient{} }, - - // Types (pointer type) - "NewIsOracleResponse": func() *lib_oracle.IsOracleResponse { return &lib_oracle.IsOracleResponse{} }, - "NewOracleClient": func() *lib_oracle.OracleClient { return &lib_oracle.OracleClient{} }, + // Objects / Classes + "IsOracleResponse": gojs.GetClassConstructor[lib_oracle.IsOracleResponse](&lib_oracle.IsOracleResponse{}), + "OracleClient": gojs.GetClassConstructor[lib_oracle.OracleClient](&lib_oracle.OracleClient{}), }, ).Register() } diff --git a/pkg/js/generated/go/libpop3/pop3.go b/pkg/js/generated/go/libpop3/pop3.go index d1e7a865fb..a43fbe0083 100644 --- a/pkg/js/generated/go/libpop3/pop3.go +++ b/pkg/js/generated/go/libpop3/pop3.go @@ -18,13 +18,9 @@ func init() { // Var and consts - // Types (value type) - "IsPOP3Response": func() lib_pop3.IsPOP3Response { return lib_pop3.IsPOP3Response{} }, - "Pop3Client": func() lib_pop3.Pop3Client { return lib_pop3.Pop3Client{} }, - - // Types (pointer type) - "NewIsPOP3Response": func() *lib_pop3.IsPOP3Response { return &lib_pop3.IsPOP3Response{} }, - "NewPop3Client": func() *lib_pop3.Pop3Client { return &lib_pop3.Pop3Client{} }, + // Objects / Classes + "IsPOP3Response": gojs.GetClassConstructor[lib_pop3.IsPOP3Response](&lib_pop3.IsPOP3Response{}), + "Pop3Client": gojs.GetClassConstructor[lib_pop3.Pop3Client](&lib_pop3.Pop3Client{}), }, ).Register() } diff --git a/pkg/js/generated/go/libpostgres/postgres.go b/pkg/js/generated/go/libpostgres/postgres.go index 0af652397e..0230c75b86 100644 --- a/pkg/js/generated/go/libpostgres/postgres.go +++ b/pkg/js/generated/go/libpostgres/postgres.go @@ -18,11 +18,8 @@ func init() { // Var and consts - // Types (value type) - "PGClient": func() lib_postgres.PGClient { return lib_postgres.PGClient{} }, - - // Types (pointer type) - "NewPGClient": func() *lib_postgres.PGClient { return &lib_postgres.PGClient{} }, + // Objects / Classes + "PGClient": gojs.GetClassConstructor[lib_postgres.PGClient](&lib_postgres.PGClient{}), }, ).Register() } diff --git a/pkg/js/generated/go/librdp/rdp.go b/pkg/js/generated/go/librdp/rdp.go index c975fe7783..1b5591775f 100644 --- a/pkg/js/generated/go/librdp/rdp.go +++ b/pkg/js/generated/go/librdp/rdp.go @@ -18,15 +18,10 @@ func init() { // Var and consts - // Types (value type) - "CheckRDPAuthResponse": func() lib_rdp.CheckRDPAuthResponse { return lib_rdp.CheckRDPAuthResponse{} }, - "IsRDPResponse": func() lib_rdp.IsRDPResponse { return lib_rdp.IsRDPResponse{} }, - "RDPClient": func() lib_rdp.RDPClient { return lib_rdp.RDPClient{} }, - - // Types (pointer type) - "NewCheckRDPAuthResponse": func() *lib_rdp.CheckRDPAuthResponse { return &lib_rdp.CheckRDPAuthResponse{} }, - "NewIsRDPResponse": func() *lib_rdp.IsRDPResponse { return &lib_rdp.IsRDPResponse{} }, - "NewRDPClient": func() *lib_rdp.RDPClient { return &lib_rdp.RDPClient{} }, + // Objects / Classes + "CheckRDPAuthResponse": gojs.GetClassConstructor[lib_rdp.CheckRDPAuthResponse](&lib_rdp.CheckRDPAuthResponse{}), + "IsRDPResponse": gojs.GetClassConstructor[lib_rdp.IsRDPResponse](&lib_rdp.IsRDPResponse{}), + "RDPClient": gojs.GetClassConstructor[lib_rdp.RDPClient](&lib_rdp.RDPClient{}), }, ).Register() } diff --git a/pkg/js/generated/go/libredis/redis.go b/pkg/js/generated/go/libredis/redis.go index 06aa37da79..a633afd846 100644 --- a/pkg/js/generated/go/libredis/redis.go +++ b/pkg/js/generated/go/libredis/redis.go @@ -23,9 +23,8 @@ func init() { // Var and consts - // Types (value type) + // Objects / Classes - // Types (pointer type) }, ).Register() } diff --git a/pkg/js/generated/go/librsync/rsync.go b/pkg/js/generated/go/librsync/rsync.go index 51baab04bd..759fc1ff98 100644 --- a/pkg/js/generated/go/librsync/rsync.go +++ b/pkg/js/generated/go/librsync/rsync.go @@ -18,13 +18,9 @@ func init() { // Var and consts - // Types (value type) - "IsRsyncResponse": func() lib_rsync.IsRsyncResponse { return lib_rsync.IsRsyncResponse{} }, - "RsyncClient": func() lib_rsync.RsyncClient { return lib_rsync.RsyncClient{} }, - - // Types (pointer type) - "NewIsRsyncResponse": func() *lib_rsync.IsRsyncResponse { return &lib_rsync.IsRsyncResponse{} }, - "NewRsyncClient": func() *lib_rsync.RsyncClient { return &lib_rsync.RsyncClient{} }, + // Objects / Classes + "IsRsyncResponse": gojs.GetClassConstructor[lib_rsync.IsRsyncResponse](&lib_rsync.IsRsyncResponse{}), + "RsyncClient": gojs.GetClassConstructor[lib_rsync.RsyncClient](&lib_rsync.RsyncClient{}), }, ).Register() } diff --git a/pkg/js/generated/go/libsmb/smb.go b/pkg/js/generated/go/libsmb/smb.go index 5181881a84..2afe53c687 100644 --- a/pkg/js/generated/go/libsmb/smb.go +++ b/pkg/js/generated/go/libsmb/smb.go @@ -18,11 +18,8 @@ func init() { // Var and consts - // Types (value type) - "SMBClient": func() lib_smb.SMBClient { return lib_smb.SMBClient{} }, - - // Types (pointer type) - "NewSMBClient": func() *lib_smb.SMBClient { return &lib_smb.SMBClient{} }, + // Objects / Classes + "SMBClient": gojs.GetClassConstructor[lib_smb.SMBClient](&lib_smb.SMBClient{}), }, ).Register() } diff --git a/pkg/js/generated/go/libsmtp/smtp.go b/pkg/js/generated/go/libsmtp/smtp.go index 75b83bd3ea..07388de8c2 100644 --- a/pkg/js/generated/go/libsmtp/smtp.go +++ b/pkg/js/generated/go/libsmtp/smtp.go @@ -18,15 +18,10 @@ func init() { // Var and consts - // Types (value type) - "IsSMTPResponse": func() lib_smtp.IsSMTPResponse { return lib_smtp.IsSMTPResponse{} }, - "SMTPClient": func() lib_smtp.SMTPClient { return lib_smtp.SMTPClient{} }, - "SMTPMessage": func() lib_smtp.SMTPMessage { return lib_smtp.SMTPMessage{} }, - - // Types (pointer type) - "NewIsSMTPResponse": func() *lib_smtp.IsSMTPResponse { return &lib_smtp.IsSMTPResponse{} }, - "NewSMTPClient": func() *lib_smtp.SMTPClient { return &lib_smtp.SMTPClient{} }, - "NewSMTPMessage": func() *lib_smtp.SMTPMessage { return &lib_smtp.SMTPMessage{} }, + // Objects / Classes + "IsSMTPResponse": gojs.GetClassConstructor[lib_smtp.IsSMTPResponse](&lib_smtp.IsSMTPResponse{}), + "SMTPClient": gojs.GetClassConstructor[lib_smtp.SMTPClient](&lib_smtp.SMTPClient{}), + "SMTPMessage": gojs.GetClassConstructor[lib_smtp.SMTPMessage](&lib_smtp.SMTPMessage{}), }, ).Register() } diff --git a/pkg/js/generated/go/libssh/ssh.go b/pkg/js/generated/go/libssh/ssh.go index 9341f7df9e..6a36f51eb9 100644 --- a/pkg/js/generated/go/libssh/ssh.go +++ b/pkg/js/generated/go/libssh/ssh.go @@ -18,11 +18,8 @@ func init() { // Var and consts - // Types (value type) - "SSHClient": func() lib_ssh.SSHClient { return lib_ssh.SSHClient{} }, - - // Types (pointer type) - "NewSSHClient": func() *lib_ssh.SSHClient { return &lib_ssh.SSHClient{} }, + // Objects / Classes + "SSHClient": gojs.GetClassConstructor[lib_ssh.SSHClient](&lib_ssh.SSHClient{}), }, ).Register() } diff --git a/pkg/js/generated/go/libstructs/structs.go b/pkg/js/generated/go/libstructs/structs.go index b11fb5fb53..e17e629dd4 100644 --- a/pkg/js/generated/go/libstructs/structs.go +++ b/pkg/js/generated/go/libstructs/structs.go @@ -21,9 +21,8 @@ func init() { // Var and consts - // Types (value type) + // Objects / Classes - // Types (pointer type) }, ).Register() } diff --git a/pkg/js/generated/go/libtelnet/telnet.go b/pkg/js/generated/go/libtelnet/telnet.go index cf43761d29..1aa191aaf6 100644 --- a/pkg/js/generated/go/libtelnet/telnet.go +++ b/pkg/js/generated/go/libtelnet/telnet.go @@ -18,13 +18,9 @@ func init() { // Var and consts - // Types (value type) - "IsTelnetResponse": func() lib_telnet.IsTelnetResponse { return lib_telnet.IsTelnetResponse{} }, - "TelnetClient": func() lib_telnet.TelnetClient { return lib_telnet.TelnetClient{} }, - - // Types (pointer type) - "NewIsTelnetResponse": func() *lib_telnet.IsTelnetResponse { return &lib_telnet.IsTelnetResponse{} }, - "NewTelnetClient": func() *lib_telnet.TelnetClient { return &lib_telnet.TelnetClient{} }, + // Objects / Classes + "IsTelnetResponse": gojs.GetClassConstructor[lib_telnet.IsTelnetResponse](&lib_telnet.IsTelnetResponse{}), + "TelnetClient": gojs.GetClassConstructor[lib_telnet.TelnetClient](&lib_telnet.TelnetClient{}), }, ).Register() } diff --git a/pkg/js/generated/go/libvnc/vnc.go b/pkg/js/generated/go/libvnc/vnc.go index cb0e2fd5d1..11a9144942 100644 --- a/pkg/js/generated/go/libvnc/vnc.go +++ b/pkg/js/generated/go/libvnc/vnc.go @@ -18,13 +18,9 @@ func init() { // Var and consts - // Types (value type) - "IsVNCResponse": func() lib_vnc.IsVNCResponse { return lib_vnc.IsVNCResponse{} }, - "VNCClient": func() lib_vnc.VNCClient { return lib_vnc.VNCClient{} }, - - // Types (pointer type) - "NewIsVNCResponse": func() *lib_vnc.IsVNCResponse { return &lib_vnc.IsVNCResponse{} }, - "NewVNCClient": func() *lib_vnc.VNCClient { return &lib_vnc.VNCClient{} }, + // Objects / Classes + "IsVNCResponse": gojs.GetClassConstructor[lib_vnc.IsVNCResponse](&lib_vnc.IsVNCResponse{}), + "VNCClient": gojs.GetClassConstructor[lib_vnc.VNCClient](&lib_vnc.VNCClient{}), }, ).Register() } diff --git a/pkg/js/generated/js/global.js b/pkg/js/generated/js/global.js deleted file mode 100644 index bcbdfd7a5c..0000000000 --- a/pkg/js/generated/js/global.js +++ /dev/null @@ -1,86 +0,0 @@ -/** - * @function - * @description Rand returns a random byte slice of length n - * @param {number} n - The length of the byte slice. - * @returns {Uint8Array} - The random byte slice. - * @example - * let randbytes = Rand(10); // returns a random byte slice of length 10 - */ -function Rand(n) { - // implemented in go -}; - -/** - * @function - * @description RandInt returns a random int - * @returns {number} - The random integer. - * @example - * let myint = m.RandInt(); // returns a random int - */ -function RandInt() { - // implemented in go -}; - -/** - * @function - * @description log prints given input to stdout with [JS] prefix for debugging purposes - * @param {string|Object} msg - The message to print. - * @example - * log("Hello World!"); - * log({"Hello": "World!"}); - */ -function log(msg) { - // implemented in go -}; - -/** - * @function - * @description getNetworkPort registers defaultPort and returns defaultPort if it is a colliding port with other protocols - * @param {string} port - The port to check. - * @param {string} defaultPort - The default port to return if the given port is colliding. - * @returns {string} - The default port if the given port is colliding, otherwise the given port. - * @example - * let port = getNetworkPort(Port, "2843"); // 2843 is default port (even if 80,443 etc is given in Port from input) - */ -function getNetworkPort(port, defaultPort) { - // implemented in go -}; - -/** - * @function - * @description isPortOpen checks if given port is open on host. timeout is optional and defaults to 5 seconds - * @param {string} host - The host to check. - * @param {string} port - The port to check. - * @param {number} [timeout=5] - The timeout in seconds. - * @returns {boolean} - True if the port is open, false otherwise. - * @example - * let open = isPortOpen("localhost", "80"); // returns true if port 80 is open on localhost - * let open = isPortOpen("localhost", "80", 10); // returns true if port 80 is open on localhost within 10 seconds - */ -function isPortOpen(host, port, timeout = 5) { - // implemented in go -}; - -/** - * @function - * @description ToBytes converts given input to byte slice - * @param {...any} args - The input to convert. - * @returns {Uint8Array} - The byte slice. - * @example - * let mybytes = ToBytes("Hello World!"); // returns byte slice of "Hello World!" - */ -function ToBytes(...args) { - // implemented in go -}; - -/** - * @function - * @description ToString converts given input to string - * @param {...any} args - The input to convert. - * @returns {string} - The string. - * @example - * let mystr = ToString([0x48, 0x65, 0x6c, 0x6c, 0x6f]); // returns "Hello" - */ -function ToString(...args) { - // implemented in go -}; diff --git a/pkg/js/generated/js/libbytes/bytes.js b/pkg/js/generated/js/libbytes/bytes.js deleted file mode 100644 index bd0b1f4f8e..0000000000 --- a/pkg/js/generated/js/libbytes/bytes.js +++ /dev/null @@ -1,134 +0,0 @@ -/**@module bytes */ - -/** - * @class - * @classdesc Buffer is a minimal buffer implementation to store and retrieve data - */ -class Buffer { - /** - * @method - * @description Bytes returns the byte slice of the buffer. - * @returns {Uint8Array} - The byte slice of the buffer. - * @example - * let m = require('nuclei/bytes'); - * let b = m.Buffer(); - * let bytes = b.Bytes(); - */ - Bytes() { - // implemented in go - }; - - /** - * @method - * @description Hex returns the hex representation of the buffer. - * @returns {string} - The hex representation of the buffer. - * @example - * let m = require('nuclei/bytes'); - * let b = m.Buffer(); - * let hex = b.Hex(); - */ - Hex() { - // implemented in go - }; - - /** - * @method - * @description Hexdump returns the hexdump representation of the buffer. - * @returns {string} - The hexdump representation of the buffer. - * @example - * let m = require('nuclei/bytes'); - * let b = m.Buffer(); - * let hexdump = b.Hexdump(); - */ - Hexdump() { - // implemented in go - }; - - /** - * @method - * @description Len returns the length of the buffer. - * @returns {number} - The length of the buffer. - * @example - * let m = require('nuclei/bytes'); - * let b = m.Buffer(); - * let length = b.Len(); - */ - Len() { - // implemented in go - }; - - /** - * @method - * @description Pack uses structs.Pack and packs given data and appends it to the buffer. It packs the data according to the given format. - * @param {string} formatStr - The format string to pack the data. - * @param {string} msg - The message to pack. - * @returns {Buffer} - The buffer after packing the data. - * @throws {error} - The error encountered during packing. - * @example - * let m = require('nuclei/bytes'); - * let b = m.Buffer(); - * b.Pack('format', 'message'); - */ - Pack(formatStr, msg) { - // implemented in go - }; - - /** - * @method - * @description String returns the string representation of the buffer. - * @returns {string} - The string representation of the buffer. - * @example - * let m = require('nuclei/bytes'); - * let b = m.Buffer(); - * let str = b.String(); - */ - String() { - // implemented in go - }; - - /** - * @method - * @description Write appends a byte slice to the buffer. - * @param {Uint8Array} data - The byte slice to append to the buffer. - * @returns {Buffer} - The buffer after appending the byte slice. - * @example - * let m = require('nuclei/bytes'); - * let b = m.Buffer(); - * b.Write(new Uint8Array([1, 2, 3])); - */ - Write(data) { - // implemented in go - }; - - /** - * @method - * @description WriteString appends a string to the buffer. - * @param {string} data - The string to append to the buffer. - * @returns {Buffer} - The buffer after appending the string. - * @example - * let m = require('nuclei/bytes'); - * let b = m.Buffer(); - * b.WriteString('data'); - */ - WriteString(data) { - // implemented in go - }; -}; - -/** - * @function - * @description NewBuffer creates a new buffer from a byte slice. - * @param {Uint8Array} call - The byte slice to create the buffer from. - * @returns {Buffer} - The new buffer created from the byte slice. - * @example - * let m = require('nuclei/bytes'); - * let buffer = m.NewBuffer(new Uint8Array([1, 2, 3])); - */ -function NewBuffer(call) { - // implemented in go -}; - -module.exports = { - Buffer: Buffer, - NewBuffer: NewBuffer, -}; \ No newline at end of file diff --git a/pkg/js/generated/js/libfs/fs.js b/pkg/js/generated/js/libfs/fs.js deleted file mode 100644 index 026c07ab76..0000000000 --- a/pkg/js/generated/js/libfs/fs.js +++ /dev/null @@ -1,65 +0,0 @@ -/** @module fs */ - -/** - * @function - * @description ListDir lists all files and directories within a path depending on the itemType provided. itemType can be any one of ['file','dir','all'] - * @param {string} path - The path to list files and directories from. - * @param {string} itemType - The type of items to list. Can be 'file', 'dir', or 'all'. - * @returns {string[]} - The list of files and directories. - * @throws {error} - The error encountered during listing. - * @example - * let m = require('nuclei/fs'); - * let items = m.ListDir('/tmp', 'all'); - */ -function ListDir(path, itemType) { - // implemented in go -}; - -/** - * @function - * @description ReadFile reads file contents within permitted paths - * @param {string} path - The path to the file to read. - * @returns {Uint8Array} - The contents of the file. - * @throws {error} - The error encountered during reading. - * @example - * let m = require('nuclei/fs'); - * let content = m.ReadFile('/tmp/myfile.txt'); - */ -function ReadFile(path) { - // implemented in go -}; - -/** - * @function - * @description ReadFileAsString reads file contents within permitted paths and returns content as string - * @param {string} path - The path to the file to read. - * @returns {string} - The contents of the file as a string. - * @throws {error} - The error encountered during reading. - * @example - * let m = require('nuclei/fs'); - * let content = m.ReadFileAsString('/tmp/myfile.txt'); - */ -function ReadFileAsString(path) { - // implemented in go -}; - -/** - * @function - * @description ReadFilesFromDir reads all files from a directory and returns a array with file contents of all files - * @param {string} dir - The directory to read files from. - * @returns {string[]} - The contents of all files in the directory. - * @throws {error} - The error encountered during reading. - * @example - * let m = require('nuclei/fs'); - * let contentArray = m.ReadFilesFromDir('/tmp'); - */ -function ReadFilesFromDir(dir) { - // implemented in go -}; - -module.exports = { - ListDir: ListDir, - ReadFile: ReadFile, - ReadFileAsString: ReadFileAsString, - ReadFilesFromDir: ReadFilesFromDir, -}; \ No newline at end of file diff --git a/pkg/js/generated/js/libgoconsole/goconsole.js b/pkg/js/generated/js/libgoconsole/goconsole.js deleted file mode 100644 index deeddd97ed..0000000000 --- a/pkg/js/generated/js/libgoconsole/goconsole.js +++ /dev/null @@ -1,63 +0,0 @@ -/** @module goconsole */ - -/** - * @class - * @classdesc GoConsolePrinter is a console printer for nuclei using gologger - */ -class GoConsolePrinter { - /** - * @method - * @description Error logs an error message - * @param {string} msg - The message to log. - * @example - * let m = require('nuclei/goconsole'); - * let c = m.GoConsolePrinter(); - * c.Error('This is an error message'); - */ - Error(msg) { - // implemented in go - }; - - /** - * @method - * @description Log logs a message - * @param {string} msg - The message to log. - * @example - * let m = require('nuclei/goconsole'); - * let c = m.GoConsolePrinter(); - * c.Log('This is a log message'); - */ - Log(msg) { - // implemented in go - }; - - /** - * @method - * @description Warn logs a warning message - * @param {string} msg - The message to log. - * @example - * let m = require('nuclei/goconsole'); - * let c = m.GoConsolePrinter(); - * c.Warn('This is a warning message'); - */ - Warn(msg) { - // implemented in go - }; -}; - -/** - * @function - * @description NewGoConsolePrinter creates a new instance of GoConsolePrinter - * @returns {GoConsolePrinter} - The new instance of GoConsolePrinter. - * @example - * let m = require('nuclei/goconsole'); - * let printer = m.NewGoConsolePrinter(); - */ -function NewGoConsolePrinter() { - // implemented in go -}; - -module.exports = { - GoConsolePrinter: GoConsolePrinter, - NewGoConsolePrinter: NewGoConsolePrinter, -}; \ No newline at end of file diff --git a/pkg/js/generated/js/libikev2/ikev2.js b/pkg/js/generated/js/libikev2/ikev2.js deleted file mode 100644 index 46fda80126..0000000000 --- a/pkg/js/generated/js/libikev2/ikev2.js +++ /dev/null @@ -1,38 +0,0 @@ -/** @module ikev2 */ - -/** - * @class - * @classdesc IKEMessage is the IKEv2 message. IKEv2 implements a limited subset of IKEv2 Protocol, specifically the IKE_NOTIFY and IKE_NONCE payloads and the IKE_SA_INIT exchange. - */ -class IKEMessage { - /** - * @method - * @description AppendPayload appends a payload to the IKE message - * @param {object} payload - The payload to append to the IKE message. - * @example - * let m = require('nuclei/ikev2'); - * let ike = m.IKEMessage(); - * ike.AppendPayload({data: 'test'}); - */ - AppendPayload(payload) { - // implemented in go - }; - - /** - * @method - * @description Encode encodes the final IKE message - * @returns {Uint8Array} - The encoded IKE message. - * @throws {error} - The error encountered during encoding. - * @example - * let m = require('nuclei/ikev2'); - * let ike = m.IKEMessage(); - * let encoded = ike.Encode(); - */ - Encode() { - // implemented in go - }; -}; - -module.exports = { - IKEMessage: IKEMessage, -}; \ No newline at end of file diff --git a/pkg/js/generated/js/libkerberos/kerberos.js b/pkg/js/generated/js/libkerberos/kerberos.js deleted file mode 100644 index 4f73770501..0000000000 --- a/pkg/js/generated/js/libkerberos/kerberos.js +++ /dev/null @@ -1,34 +0,0 @@ -/** @module kerberos */ - -/** - * @class - * @classdesc KerberosClient is a kerberos client - */ -class KerberosClient { - /** - * @method - * @description EnumerateUser returns true if the user exists in the domain. If the user is not found, false is returned. If the user is found, true is returned. Optionally, the AS-REP hash is also returned if discovered. - * @param {string} domain - The domain to check. - * @param {string} controller - The controller to use. - * @param {string} username - The username to check. - * @returns {EnumerateUserResponse} - The response of the enumeration. - * @throws {error} - The error encountered during enumeration. - * @example - * let m = require('nuclei/kerberos'); - * let c = m.KerberosClient(); - * let response = c.EnumerateUser('domain', 'controller', 'username'); - */ - EnumerateUser(domain, controller, username) { - // implemented in go - }; -}; - -/** - * @typedef {object} EnumerateUserResponse - * @description EnumerateUserResponse is the response object from the EnumerateUser method. - */ -const EnumerateUserResponse = {}; - -module.exports = { - KerberosClient: KerberosClient, -}; \ No newline at end of file diff --git a/pkg/js/generated/js/libldap/ldap.js b/pkg/js/generated/js/libldap/ldap.js deleted file mode 100644 index 9297b9232c..0000000000 --- a/pkg/js/generated/js/libldap/ldap.js +++ /dev/null @@ -1,49 +0,0 @@ -/** @module ldap */ - -/** - * @typedef {object} LDAPMetadata - * @description LDAPMetadata is an object containing metadata from ldap server. - */ -const LDAPMetadata = {}; - -/** - * @class - * @classdesc LdapClient is a client for ldap protocol in golang. It is a wrapper around the standard library ldap package. - */ -class LdapClient { - /** - * @method - * @description CollectLdapMetadata collects metadata from ldap server. - * @param {string} domain - The domain to collect metadata from. - * @param {string} controller - The controller to collect metadata from. - * @returns {LDAPMetadata} - The metadata from ldap server. - * @throws {error} - The error encountered during metadata collection. - * @example - * let m = require('nuclei/ldap'); - * let c = m.LdapClient(); - * let metadata = c.CollectLdapMetadata('example.com', 'controller1'); - */ - CollectLdapMetadata(domain, controller) { - // implemented in go - }; - - /** - * @method - * @description IsLdap checks if the given host and port are running ldap server. - * @param {string} host - The host to check. - * @param {int} port - The port to check. - * @returns {boolean} - Whether the given host and port are running ldap server. - * @throws {error} - The error encountered during the check. - * @example - * let m = require('nuclei/ldap'); - * let c = m.LdapClient(); - * let isLdap = c.IsLdap('localhost', 389); - * */ - IsLdap(host, port) { - // implemented in go - }; -}; - -module.exports = { - LdapClient: LdapClient, -}; \ No newline at end of file diff --git a/pkg/js/generated/js/libmssql/mssql.js b/pkg/js/generated/js/libmssql/mssql.js deleted file mode 100644 index 81f5a32d9a..0000000000 --- a/pkg/js/generated/js/libmssql/mssql.js +++ /dev/null @@ -1,64 +0,0 @@ -/** @module mssql */ - -/** - * @class - * @classdesc MSSQLClient is a client for MS SQL database. Internally client uses denisenkom/go-mssqldb driver. - */ -class MSSQLClient { - /** - * @method - * @description Connect connects to MS SQL database using given credentials. If connection is successful, it returns true. If connection is unsuccessful, it returns false and error. The connection is closed after the function returns. - * @param {string} host - The host of the MS SQL database. - * @param {int} port - The port of the MS SQL database. - * @param {string} username - The username to connect to the MS SQL database. - * @param {string} password - The password to connect to the MS SQL database. - * @returns {bool} - The status of the connection. - * @throws {error} - The error encountered during connection. - * @example - * let m = require('nuclei/mssql'); - * let c = m.MSSQLClient(); - * let isConnected = c.Connect('localhost', 1433, 'username', 'password'); - */ - Connect(host, port, username, password) { - // implemented in go - }; - - /** - * @method - * @description ConnectWithDB connects to MS SQL database using given credentials and database name. If connection is successful, it returns true. If connection is unsuccessful, it returns false and error. The connection is closed after the function returns. - * @param {string} host - The host of the MS SQL database. - * @param {int} port - The port of the MS SQL database. - * @param {string} username - The username to connect to the MS SQL database. - * @param {string} password - The password to connect to the MS SQL database. - * @param {string} dbName - The name of the database to connect to. - * @returns {bool} - The status of the connection. - * @throws {error} - The error encountered during connection. - * @example - * let m = require('nuclei/mssql'); - * let c = m.MSSQLClient(); - * let isConnected = c.ConnectWithDB('localhost', 1433, 'username', 'password', 'myDatabase'); - */ - ConnectWithDB(host, port, username, password, dbName) { - // implemented in go - }; - - /** - * @method - * @description IsMssql checks if the given host is running MS SQL database. If the host is running MS SQL database, it returns true. If the host is not running MS SQL database, it returns false. - * @param {string} host - The host to check. - * @param {int} port - The port to check. - * @returns {bool} - The status of the check. - * @throws {error} - The error encountered during the check. - * @example - * let m = require('nuclei/mssql'); - * let c = m.MSSQLClient(); - * let isMssql = c.IsMssql('localhost', 1433); - */ - IsMssql(host, port) { - // implemented in go - }; -}; - -module.exports = { - MSSQLClient: MSSQLClient, -}; \ No newline at end of file diff --git a/pkg/js/generated/js/libmysql/mysql.js b/pkg/js/generated/js/libmysql/mysql.js deleted file mode 100644 index afa5a22e79..0000000000 --- a/pkg/js/generated/js/libmysql/mysql.js +++ /dev/null @@ -1,84 +0,0 @@ -/** @module mysql */ - -/** - * @class - * @classdesc MySQLClient is a client for MySQL database. Internally client uses go-sql-driver/mysql driver. - */ -class MySQLClient { - /** - * @method - * @description Connect connects to MySQL database using given credentials. If connection is successful, it returns true. If connection is unsuccessful, it returns false and error. The connection is closed after the function returns. - * @param {string} host - The host of the MySQL database. - * @param {int} port - The port of the MySQL database. - * @param {string} username - The username to connect to the MySQL database. - * @param {string} password - The password to connect to the MySQL database. - * @returns {bool} - The result of the connection attempt. - * @throws {error} - The error encountered during connection attempt. - * @example - * let m = require('nuclei/mysql'); - * let c = m.MySQLClient(); - * let result = c.Connect('localhost', 3306, 'root', 'password'); - */ - Connect(host, port, username, password) { - // implemented in go - }; - - /** - * @method - * @description ConnectWithDB connects to MySQL database using given credentials and database name. If connection is successful, it returns true. If connection is unsuccessful, it returns false and error. The connection is closed after the function returns. - * @param {string} host - The host of the MySQL database. - * @param {int} port - The port of the MySQL database. - * @param {string} username - The username to connect to the MySQL database. - * @param {string} password - The password to connect to the MySQL database. - * @param {string} dbName - The name of the database to connect to. - * @returns {bool} - The result of the connection attempt. - * @throws {error} - The error encountered during connection attempt. - * @example - * let m = require('nuclei/mysql'); - * let c = m.MySQLClient(); - * let result = c.ConnectWithDB('localhost', 3306, 'root', 'password', 'mydb'); - */ - ConnectWithDB(host, port, username, password, dbName) { - // implemented in go - }; - - /** - * @method - * @description ExecuteQuery connects to Mysql database using given credentials and database name and executes a query on the db. - * @param {string} host - The host of the MySQL database. - * @param {int} port - The port of the MySQL database. - * @param {string} username - The username to connect to the MySQL database. - * @param {string} password - The password to connect to the MySQL database. - * @param {string} dbName - The name of the database to connect to. - * @param {string} query - The query to execute on the database. - * @returns {string} - The result of the query execution. - * @throws {error} - The error encountered during query execution. - * @example - * let m = require('nuclei/mysql'); - * let c = m.MySQLClient(); - * let result = c.ExecuteQuery('localhost', 3306, 'root', 'password', 'mydb', 'SELECT * FROM users'); - */ - ExecuteQuery(host, port, username, password, dbName, query) { - // implemented in go - }; - - /** - * @method - * @description IsMySQL checks if the given host is running MySQL database. If the host is running MySQL database, it returns true. If the host is not running MySQL database, it returns false. - * @param {string} host - The host to check. - * @param {int} port - The port to check. - * @returns {bool} - The result of the check. - * @throws {error} - The error encountered during the check. - * @example - * let m = require('nuclei/mysql'); - * let c = m.MySQLClient(); - * let result = c.IsMySQL('localhost', 3306); - */ - IsMySQL(host, port) { - // implemented in go - }; -}; - -module.exports = { - MySQLClient: MySQLClient, -}; \ No newline at end of file diff --git a/pkg/js/generated/js/libnet/net.js b/pkg/js/generated/js/libnet/net.js deleted file mode 100644 index 40e830b5d5..0000000000 --- a/pkg/js/generated/js/libnet/net.js +++ /dev/null @@ -1,156 +0,0 @@ -/**@module net */ - -/** - * @class - * @classdesc NetConn is a connection to a remote host. - */ -class NetConn { - /** - * @method - * @description Close closes the connection. - * @throws {error} - The error encountered during connection closing. - * @example - * let m = require('nuclei/net'); - * let c = m.Open('tcp', 'localhost:8080'); - * c.Close(); - */ - Close() { - // implemented in go - }; - - /** - * @method - * @description Recv receives data from the connection with a timeout. If N is 0, it will read all available data. - * @param {number} [N=0] - The number of bytes to receive. - * @returns {Uint8Array} - The received data in an array. - * @throws {error} - The error encountered during data receiving. - * @example - * let m = require('nuclei/net'); - * let c = m.Open('tcp', 'localhost:8080'); - * let data = c.Recv(1024); - */ - Recv(N) { - // implemented in go - }; - - /** - * @method - * @description RecvHex receives data from the connection with a timeout in hex format. If N is 0, it will read all available data. - * @param {number} [N=0] - The number of bytes to receive. - * @returns {string} - The received data in hex format. - * @throws {error} - The error encountered during data receiving. - * @example - * let m = require('nuclei/net'); - * let c = m.Open('tcp', 'localhost:8080'); - * let data = c.RecvHex(1024); - */ - RecvHex(N) { - // implemented in go - }; - - /** - * @method - * @description RecvString receives data from the connection with a timeout. Output is returned as a string. If N is 0, it will read all available data. - * @param {number} [N=0] - The number of bytes to receive. - * @returns {string} - The received data as a string. - * @throws {error} - The error encountered during data receiving. - * @example - * let m = require('nuclei/net'); - * let c = m.Open('tcp', 'localhost:8080'); - * let data = c.RecvString(1024); - */ - RecvString(N) { - // implemented in go - }; - - /** - * @method - * @description Send sends data to the connection with a timeout. - * @param {Uint8Array} data - The data to send. - * @throws {error} - The error encountered during data sending. - * @example - * let m = require('nuclei/net'); - * let c = m.Open('tcp', 'localhost:8080'); - * c.Send(new Uint8Array([1, 2, 3])); - */ - Send(data) { - // implemented in go - }; - - /** - * @method - * @description SendArray sends array data to connection. - * @param {Uint8Array} data - The array data to send. - * @throws {error} - The error encountered during data sending. - * @example - * let m = require('nuclei/net'); - * let c = m.Open('tcp', 'localhost:8080'); - * c.SendArray(new Uint8Array([1, 2, 3])); - */ - SendArray(data) { - // implemented in go - }; - - /** - * @method - * @description SendHex sends hex data to connection. - * @param {string} data - The hex data to send. - * @throws {error} - The error encountered during data sending. - * @example - * let m = require('nuclei/net'); - * let c = m.Open('tcp', 'localhost:8080'); - * c.SendHex('0x123'); - */ - SendHex(data) { - // implemented in go - }; - - /** - * @method - * @description SetTimeout sets read/write timeout for the connection (in seconds). - * @param {number} value - The timeout value in seconds. - * @example - * let m = require('nuclei/net'); - * let c = m.Open('tcp', 'localhost:8080'); - * c.SetTimeout(5); - */ - SetTimeout(value) { - // implemented in go - }; -}; - -/** - * @function - * @description Open opens a new connection to the address with a timeout. Supported protocols: tcp, udp. - * @param {string} protocol - The protocol to use. - * @param {string} address - The address to connect to. - * @returns {NetConn} - The NetConn object representing the connection. - * @throws {error} - The error encountered during connection opening. - * @example - * let m = require('nuclei/net'); - * let conn = m.Open('tcp', 'localhost:8080'); - */ -function Open(protocol, address) { - // implemented in go -}; - -/** - * @function - * @description OpenTLS opens a new connection to the address with a timeout. Supported protocols: tcp, udp. - * @param {string} protocol - The protocol to use. - * @param {string} address - The address to connect to. - * @returns {NetConn} - The NetConn object representing the connection. - * @throws {error} - The error encountered during connection opening. - * @example - * let m = require('nuclei/net'); - * let conn = m.OpenTLS('tcp', 'localhost:8080'); - */ -function OpenTLS(protocol, address) { - // implemented in go -}; - -module.exports = { - NetConn: NetConn, - Open: Open, - OpenTLS: OpenTLS, -}; \ No newline at end of file diff --git a/pkg/js/generated/js/liboracle/oracle.js b/pkg/js/generated/js/liboracle/oracle.js deleted file mode 100644 index 2341342d7a..0000000000 --- a/pkg/js/generated/js/liboracle/oracle.js +++ /dev/null @@ -1,33 +0,0 @@ -/** @module oracle */ - -/** - * @class - * @classdesc OracleClient is a minimal Oracle client for nuclei scripts. - */ -class OracleClient { - /** - * @method - * @description IsOracle checks if a host is running an Oracle server. - * @param {string} host - The host to check. - * @param {int} port - The port to check. - * @returns {IsOracleResponse} - The response from the Oracle server. - * @throws {error} - The error encountered during the check. - * @example - * let m = require('nuclei/oracle'); - * let c = m.OracleClient(); - * let response = c.IsOracle('localhost', 1521); - */ - IsOracle(host, port) { - // implemented in go - }; -}; - -/** - * @typedef {object} IsOracleResponse - * @description IsOracleResponse is an object containing the response from the Oracle server. - */ -const IsOracleResponse = {}; - -module.exports = { - OracleClient: OracleClient, -}; \ No newline at end of file diff --git a/pkg/js/generated/js/libpop3/pop3.js b/pkg/js/generated/js/libpop3/pop3.js deleted file mode 100644 index 595efa3fcb..0000000000 --- a/pkg/js/generated/js/libpop3/pop3.js +++ /dev/null @@ -1,33 +0,0 @@ -/** @module pop3 */ - -/** - * @class - * @classdesc Pop3Client is a minimal POP3 client for nuclei scripts - */ -class Pop3Client { - /** - * @method - * @description IsPOP3 checks if a host is running a POP3 server - * @param {string} host - The host to check. - * @param {number} port - The port to check. - * @returns {IsPOP3Response} - The response of the check. - * @throws {error} - The error encountered during the check. - * @example - * let m = require('nuclei/pop3'); - * let c = m.Pop3Client(); - * let response = c.IsPOP3('localhost', 110); - */ - IsPOP3(host, port) { - // implemented in go - }; -}; - -/** - * @typedef {object} IsPOP3Response - * @description IsPOP3Response is an object containing the response of the IsPOP3 check. - */ -const IsPOP3Response = {}; - -module.exports = { - Pop3Client: Pop3Client, -}; \ No newline at end of file diff --git a/pkg/js/generated/js/libpostgres/postgres.js b/pkg/js/generated/js/libpostgres/postgres.js deleted file mode 100644 index 71588f6b97..0000000000 --- a/pkg/js/generated/js/libpostgres/postgres.js +++ /dev/null @@ -1,84 +0,0 @@ -/** @module postgres */ - -/** - * @class - * @classdesc PGClient is a client for Postgres database. Internally client uses go-pg/pg driver. - */ -class PGClient { - /** - * @method - * @description Connect connects to Postgres database using given credentials. The connection is closed after the function returns. - * @param {string} host - The host of the Postgres database. - * @param {int} port - The port of the Postgres database. - * @param {string} username - The username to connect to the Postgres database. - * @param {string} password - The password to connect to the Postgres database. - * @returns {bool} - If connection is successful, it returns true. - * @throws {error} - If connection is unsuccessful, it returns the error. - * @example - * let m = require('nuclei/postgres'); - * let c = m.PGClient(); - * let isConnected = c.Connect('localhost', 5432, 'username', 'password'); - */ - Connect(host, port, username, password) { - // implemented in go - }; - - /** - * @method - * @description ConnectWithDB connects to Postgres database using given credentials and database name. The connection is closed after the function returns. - * @param {string} host - The host of the Postgres database. - * @param {int} port - The port of the Postgres database. - * @param {string} username - The username to connect to the Postgres database. - * @param {string} password - The password to connect to the Postgres database. - * @param {string} dbName - The name of the database to connect to. - * @returns {bool} - If connection is successful, it returns true. - * @throws {error} - If connection is unsuccessful, it returns the error. - * @example - * let m = require('nuclei/postgres'); - * let c = m.PGClient(); - * let isConnected = c.ConnectWithDB('localhost', 5432, 'username', 'password', 'mydb'); - */ - ConnectWithDB(host, port, username, password, dbName) { - // implemented in go - }; - - /** - * @method - * @description ExecuteQuery connects to Postgres database using given credentials and database name and executes a query on the db. - * @param {string} host - The host of the Postgres database. - * @param {int} port - The port of the Postgres database. - * @param {string} username - The username to connect to the Postgres database. - * @param {string} password - The password to connect to the Postgres database. - * @param {string} dbName - The name of the database to connect to. - * @param {string} query - The query to execute on the database. - * @returns {string} - The result of the query execution. - * @throws {error} - If query execution is unsuccessful, it returns the error. - * @example - * let m = require('nuclei/postgres'); - * let c = m.PGClient(); - * let result = c.ExecuteQuery('localhost', 5432, 'username', 'password', 'mydb', 'SELECT * FROM users'); - */ - ExecuteQuery(host, port, username, password, dbName, query) { - // implemented in go - }; - - /** - * @method - * @description IsPostgres checks if the given host and port are running Postgres database. - * @param {string} host - The host to check. - * @param {int} port - The port to check. - * @returns {bool} - If the host and port are running Postgres database, it returns true. - * @throws {error} - If the check is unsuccessful, it returns the error. - * @example - * let m = require('nuclei/postgres'); - * let c = m.PGClient(); - * let isPostgres = c.IsPostgres('localhost', 5432); - */ - IsPostgres(host, port) { - // implemented in go - }; -}; - -module.exports = { - PGClient: PGClient, -}; \ No newline at end of file diff --git a/pkg/js/generated/js/librdp/rdp.js b/pkg/js/generated/js/librdp/rdp.js deleted file mode 100644 index 456837dc37..0000000000 --- a/pkg/js/generated/js/librdp/rdp.js +++ /dev/null @@ -1,55 +0,0 @@ -/**@module rdp */ - -/** - * @class - * @classdesc RDPClient is a client for rdp servers - */ -class RDPClient { - /** - * @method - * @description CheckRDPAuth checks if the given host and port are running rdp server with authentication and returns their metadata. - * @param {string} host - The host to check. - * @param {number} port - The port to check. - * @returns {CheckRDPAuthResponse} - The response from the check. - * @throws {error} - The error encountered during the check. - * @example - * let m = require('nuclei/rdp'); - * let c = m.RDPClient(); - * let response = c.CheckRDPAuth('localhost', 3389); - */ - CheckRDPAuth(host, port) { - // implemented in go - }; - - /** - * @method - * @description IsRDP checks if the given host and port are running rdp server. If connection is successful, it returns true. If connection is unsuccessful, it returns false and error. The Name of the OS is also returned if the connection is successful. - * @param {string} host - The host to check. - * @param {number} port - The port to check. - * @returns {IsRDPResponse} - The response from the check. - * @throws {error} - The error encountered during the check. - * @example - * let m = require('nuclei/rdp'); - * let c = m.RDPClient(); - * let response = c.IsRDP('localhost', 3389); - */ - IsRDP(host, port) { - // implemented in go - }; -}; - -/** - * @typedef {object} CheckRDPAuthResponse - * @description CheckRDPAuthResponse is the response from the CheckRDPAuth method. - */ -const CheckRDPAuthResponse = {}; - -/** - * @typedef {object} IsRDPResponse - * @description IsRDPResponse is the response from the IsRDP method. - */ -const IsRDPResponse = {}; - -module.exports = { - RDPClient: RDPClient, -}; \ No newline at end of file diff --git a/pkg/js/generated/js/libredis/redis.js b/pkg/js/generated/js/libredis/redis.js deleted file mode 100644 index bbff60b437..0000000000 --- a/pkg/js/generated/js/libredis/redis.js +++ /dev/null @@ -1,87 +0,0 @@ -/** @module redis */ - -/** - * @function - * @description Connect tries to connect redis server with password - * @param {string} host - The host of the redis server. - * @param {number} port - The port of the redis server. - * @param {string} password - The password for the redis server. - * @returns {boolean} - The status of the connection. - * @throws {error} - The error encountered during connection. - * @example - * let m = require('nuclei/redis'); - * let status = m.Connect('localhost', 6379, 'password'); - */ -function Connect(host, port, password) { - // implemented in go -}; - -/** - * @function - * @description GetServerInfo returns the server info for a redis server - * @param {string} host - The host of the redis server. - * @param {number} port - The port of the redis server. - * @returns {string} - The server info. - * @throws {error} - The error encountered during getting server info. - * @example - * let m = require('nuclei/redis'); - * let info = m.GetServerInfo('localhost', 6379); - */ -function GetServerInfo(host, port) { - // implemented in go -}; - -/** - * @function - * @description GetServerInfoAuth returns the server info for a redis server - * @param {string} host - The host of the redis server. - * @param {number} port - The port of the redis server. - * @param {string} password - The password for the redis server. - * @returns {string} - The server info. - * @throws {error} - The error encountered during getting server info. - * @example - * let m = require('nuclei/redis'); - * let info = m.GetServerInfoAuth('localhost', 6379, 'password'); - */ -function GetServerInfoAuth(host, port, password) { - // implemented in go -}; - -/** - * @function - * @description IsAuthenticated checks if the redis server requires authentication - * @param {string} host - The host of the redis server. - * @param {number} port - The port of the redis server. - * @returns {boolean} - The authentication status. - * @throws {error} - The error encountered during checking authentication. - * @example - * let m = require('nuclei/redis'); - * let isAuthenticated = m.IsAuthenticated('localhost', 6379); - */ -function IsAuthenticated(host, port) { - // implemented in go -}; - -/** - * @function - * @description RunLuaScript runs a lua script on the redis server - * @param {string} host - The host of the redis server. - * @param {number} port - The port of the redis server. - * @param {string} password - The password for the redis server. - * @param {string} script - The lua script to run. - * @throws {error} - The error encountered during running the lua script. - * @example - * let m = require('nuclei/redis'); - * m.RunLuaScript('localhost', 6379, 'password', 'return redis.call(\'ping\')'); - */ -function RunLuaScript(host, port, password, script) { - // implemented in go -}; - -module.exports = { - Connect: Connect, - GetServerInfo: GetServerInfo, - GetServerInfoAuth: GetServerInfoAuth, - IsAuthenticated: IsAuthenticated, - RunLuaScript: RunLuaScript, -}; \ No newline at end of file diff --git a/pkg/js/generated/js/librsync/rsync.js b/pkg/js/generated/js/librsync/rsync.js deleted file mode 100644 index c5d1271da2..0000000000 --- a/pkg/js/generated/js/librsync/rsync.js +++ /dev/null @@ -1,33 +0,0 @@ -/** @module rsync */ - -/** - * @class - * @classdesc RsyncClient is a minimal Rsync client for nuclei scripts. - */ -class RsyncClient { - /** - * @method - * @description IsRsync checks if a host is running a Rsync server. - * @param {string} host - The host to check. - * @param {int} port - The port to check. - * @returns {IsRsyncResponse} - The response from the IsRsync check. - * @throws {error} - The error encountered during the IsRsync check. - * @example - * let m = require('nuclei/rsync'); - * let c = m.RsyncClient(); - * let response = c.IsRsync('localhost', 22); - */ - IsRsync(host, port) { - // implemented in go - }; -}; - -/** - * @typedef {object} IsRsyncResponse - * @description IsRsyncResponse is an object containing the response from the IsRsync check. - */ -const IsRsyncResponse = {}; - -module.exports = { - RsyncClient: RsyncClient, -}; \ No newline at end of file diff --git a/pkg/js/generated/js/libsmb/smb.js b/pkg/js/generated/js/libsmb/smb.js deleted file mode 100644 index a14333a591..0000000000 --- a/pkg/js/generated/js/libsmb/smb.js +++ /dev/null @@ -1,90 +0,0 @@ -/** @module smb */ - -/** - * @typedef {object} SMBLog - * @description SMBLog is an object containing the log of the SMB handshake. - */ -const SMBLog = {}; - -/** - * @typedef {object} ServiceSMB - * @description ServiceSMB is an object containing the metadata of the SMBv2 service. - */ - -const ServiceSMB = {}; - -/** - * @class - * @classdesc SMBClient is a client for SMB servers. - */ -class SMBClient { - /** - * @method - * @description ConnectSMBInfoMode tries to connect to provided host and port and discover SMB information - * @param {string} host - The host to connect to. - * @param {string} port - The port to connect to. - * @returns {SMBLog} - The log of the SMB handshake. - * @throws {error} - The error encountered during the connection. - * @example - * let m = require('nuclei/smb'); - * let c = m.SMBClient(); - * let log = c.ConnectSMBInfoMode('localhost', '445'); - */ - ConnectSMBInfoMode(host, port) { - // implemented in go - }; - - /** - * @method - * @description DetectSMBGhost tries to detect SMBGhost vulnerability by using SMBv3 compression feature. - * @param {string} host - The host to connect to. - * @param {string} port - The port to connect to. - * @returns {boolean} - The result of the SMBGhost vulnerability detection. - * @throws {error} - The error encountered during the detection. - * @example - * let m = require('nuclei/smb'); - * let c = m.SMBClient(); - * let isVulnerable = c.DetectSMBGhost('localhost', '445'); - */ - DetectSMBGhost(host, port) { - // implemented in go - }; - - /** - * @method - * @description ListSMBv2Metadata tries to connect to provided host and port and list SMBv2 metadata. - * @param {string} host - The host to connect to. - * @param {string} port - The port to connect to. - * @returns {ServiceSMB} - The metadata of the SMBv2 service. - * @throws {error} - The error encountered during the listing. - * @example - * let m = require('nuclei/smb'); - * let c = m.SMBClient(); - * let metadata = c.ListSMBv2Metadata('localhost', '445'); - */ - ListSMBv2Metadata(host, port) { - // implemented in go - }; - - /** - * @method - * @description ListShares tries to connect to provided host and port and list shares by using given credentials. - * @param {string} host - The host to connect to. - * @param {string} port - The port to connect to. - * @param {string} user - The username for authentication. - * @param {string} password - The password for authentication. - * @returns {string[]} - The list of shares. - * @throws {error} - The error encountered during the listing. - * @example - * let m = require('nuclei/smb'); - * let c = m.SMBClient(); - * let shares = c.ListShares('localhost', '445', 'user', 'password'); - */ - ListShares(host, port, user, password) { - // implemented in go - }; -}; - -module.exports = { - SMBClient: SMBClient, -}; \ No newline at end of file diff --git a/pkg/js/generated/js/libsmtp/smtp.js b/pkg/js/generated/js/libsmtp/smtp.js deleted file mode 100644 index 775c028091..0000000000 --- a/pkg/js/generated/js/libsmtp/smtp.js +++ /dev/null @@ -1,152 +0,0 @@ -/** @module smtp */ - -/** - * @class - * @classdesc SMTPClient is a minimal SMTP client for nuclei scripts. - */ -class SMTPClient { - /** - @method - @description IsOpenRelay checks if a host is an open relay - @param {string} host - The host to check. - @param {number} port - The port to check. - @param {string} msg - The message to send. - @returns {boolean} - Whether the host is an open relay or not. - @throws {error} - The error encountered during the check. - @example - let m = require('nuclei/smtp'); - let c = m.SMTPClient(); - let isOpenRelay = c.IsOpenRelay('localhost', 25, 'test message'); - */ - IsOpenRelay(host, port, msg) { - // implemented in go - }; - - /** - @method - @description IsSMTP checks if a host is running a SMTP server. - @param {string} host - The host to check. - @param {number} port - The port to check. - @returns {IsSMTPResponse} - The response from the SMTP server. - @throws {error} - The error encountered during the check. - @example - let m = require('nuclei/smtp'); - let c = m.SMTPClient(); - let isSMTP = c.IsSMTP('localhost', 25); - */ - IsSMTP(host, port) { - // implemented in go - }; - - /** - @method - @description SendMail sends an email using the SMTP protocol. - @param {string} host - The host to send the email to. - @param {number} port - The port to send the email to. - @param {string} msg - The message to send. - @returns {boolean} - Whether the email was sent successfully or not. - @throws {error} - The error encountered during the email sending. - @example - let m = require('nuclei/smtp'); - let c = m.SMTPClient(); - let isSent = c.SendMail('localhost', 25, 'test message'); - */ - SendMail(host, port, msg) { - // implemented in go - }; -}; - -/** - * @class - * @classdesc SMTPMessage is a simple smtp message builder - */ -class SMTPMessage { - /** - @method - @description Auth when called authenticates using username and password before sending the message - @param {string} username - The username for authentication. - @param {string} password - The password for authentication. - @returns {SMTPMessage} - The SMTPMessage object after authentication. - @example - let m = require('nuclei/smtp'); - let msg = m.SMTPMessage(); - msg = msg.Auth('username', 'password'); - */ - Auth(username, password) { - // implemented in go - }; - - /** - @method - @description Body adds the message body to the message - @param {string} msg - The message body to add. - @returns {SMTPMessage} - The SMTPMessage object after adding the body. - @example - let m = require('nuclei/smtp'); - let msg = m.SMTPMessage(); - msg = msg.Body('This is a test message'); - */ - Body(msg) { - // implemented in go - }; - - /** - @method - @description From adds the from field to the message - @param {string} email - The email to add to the from field. - @returns {SMTPMessage} - The SMTPMessage object after adding the from field. - @example - let m = require('nuclei/smtp'); - let msg = m.SMTPMessage(); - msg = msg.From('test@example.com'); - */ - From(email) { - // implemented in go - }; - - /** - @method - @description String returns the string representation of the message - @returns {string} - The string representation of the message. - @example - let m = require('nuclei/smtp'); - let msg = m.SMTPMessage(); - let str = msg.String(); - */ - String() { - // implemented in go - }; - - /** - @method - @description Subject adds the subject field to the message - @param {string} sub - The subject to add. - @returns {SMTPMessage} - The SMTPMessage object after adding the subject. - @example - let m = require('nuclei/smtp'); - let msg = m.SMTPMessage(); - msg = msg.Subject('Test Subject'); - */ - Subject(sub) { - // implemented in go - }; - - /** - @method - @description To adds the to field to the message - @param {string} email - The email to add to the to field. - @returns {SMTPMessage} - The SMTPMessage object after adding the to field. - @example - let m = require('nuclei/smtp'); - let msg = m.SMTPMessage(); - msg = msg.To('test@example.com'); - */ - To(email) { - // implemented in go - }; -}; - -module.exports = { - SMTPClient: SMTPClient, - SMTPMessage: SMTPMessage, -}; \ No newline at end of file diff --git a/pkg/js/generated/js/libssh/ssh.js b/pkg/js/generated/js/libssh/ssh.js deleted file mode 100644 index 984604dd9d..0000000000 --- a/pkg/js/generated/js/libssh/ssh.js +++ /dev/null @@ -1,112 +0,0 @@ -/**@module ssh */ - -/** - * @typedef {object} HandshakeLog - * @description HandshakeLog is a struct that contains information about the ssh connection. - */ -const HandshakeLog = {}; - -/** - * @class - * @classdesc SSHClient is a client for SSH servers. Internally client uses github.com/zmap/zgrab2/lib/ssh driver. - */ -class SSHClient { - /** - @method - @description Close closes the SSH connection and destroys the client - @returns {boolean} - The success state of the operation. - @throws {error} - The error encountered during the operation. - @example - let m = require('nuclei/ssh'); - let c = m.SSHClient(); - let state = c.Connect('localhost', 22, 'user', 'password'); - let result = c.Close(); - */ - Close() { - // implemented in go - }; - - /** - @method - @description Connect tries to connect to provided host and port with provided username and password with ssh. - @param {string} host - The host to connect to. - @param {number} port - The port to connect to. - @param {string} username - The username for the connection. - @param {string} password - The password for the connection. - @returns {boolean} - The success state of the operation. - @throws {error} - The error encountered during the operation. - @example - let m = require('nuclei/ssh'); - let c = m.SSHClient(); - let result = c.Connect('localhost', 22, 'user', 'password'); - */ - Connect(host, port, username, password) { - // implemented in go - }; - - /** - @method - @description ConnectSSHInfoMode tries to connect to provided host and port with provided host and port - @param {string} host - The host to connect to. - @param {number} port - The port to connect to. - @returns {HandshakeLog} - The HandshakeLog object containing information about the ssh connection. - @throws {error} - The error encountered during the operation. - @example - let m = require('nuclei/ssh'); - let c = m.SSHClient(); - let result = c.ConnectSSHInfoMode('localhost', 22); - */ - ConnectSSHInfoMode(host, port) { - // implemented in go - }; - - /** - @method - @description ConnectWithKey tries to connect to provided host and port with provided username and private_key. - @param {string} host - The host to connect to. - @param {number} port - The port to connect to. - @param {string} username - The username for the connection. - @param {string} key - The private key for the connection. - @returns {boolean} - The success state of the operation. - @throws {error} - The error encountered during the operation. - @example - let m = require('nuclei/ssh'); - let c = m.SSHClient(); - let result = c.ConnectWithKey('localhost', 22, 'user', 'key'); - */ - ConnectWithKey(host, port, username, key) { - // implemented in go - }; - - /** - @method - @description Run tries to open a new SSH session, then tries to execute the provided command in said session - @param {string} cmd - The command to execute. - @returns {string} - The output of the command. - @throws {error} - The error encountered during the operation. - @example - let m = require('nuclei/ssh'); - let c = m.SSHClient(); - let result = c.Run('ls'); - */ - Run(cmd) { - // implemented in go - }; - - /** - @method - @description SetTimeout sets the timeout for the SSH connection in seconds - @param {number} sec - The number of seconds for the timeout. - @example - let m = require('nuclei/ssh'); - let c = m.SSHClient(); - c.SetTimeout(30); - */ - SetTimeout(sec) { - // implemented in go - }; -}; - -module.exports = { - SSHClient: SSHClient, -}; \ No newline at end of file diff --git a/pkg/js/generated/js/libstructs/structs.js b/pkg/js/generated/js/libstructs/structs.js deleted file mode 100644 index 0ec94de25a..0000000000 --- a/pkg/js/generated/js/libstructs/structs.js +++ /dev/null @@ -1,54 +0,0 @@ -/**@module structs */ - -/** - * @function - * @description Pack returns a byte slice containing the values of msg slice packed according to the given format. - * The items of msg slice must match the values required by the format exactly. - * @param {string} formatStr - The format string. - * @param {any[]} msg - The message to be packed. - * @returns {Uint8Array} - The packed message in a byte array. - * @throws {error} - The error encountered during packing. - * @example - * let s = require('nuclei/structs'); - * let packedMsg = s.Pack("H", [0]); - */ -function Pack(formatStr, msg) { - // implemented in go -}; - -/** - * @function - * @description StructsCalcSize returns the number of bytes needed to pack the values according to the given format. - * @param {string} format - The format string. - * @returns {number} - The number of bytes needed to pack the values. - * @throws {error} - The error encountered during calculation. - * @example - * let s = require('nuclei/structs'); - * let size = s.StructsCalcSize("H"); - */ -function StructsCalcSize(format) { - // implemented in go -}; - -/** - * @function - * @description Unpack the byte slice (presumably packed by Pack(format, msg)) according to the given format. - * The result is a []interface{} slice even if it contains exactly one item. - * The byte slice must contain not less the amount of data required by the format - * (len(msg) must more or equal CalcSize(format)). - * @param {string} format - The format string. - * @param {Uint8Array} msg - The packed message to be unpacked. - * @throws {error} - The error encountered during unpacking. - * @example - * let s = require('nuclei/structs'); - * let unpackedMsg = s.Unpack(">I", buff[:nb]); - */ -function Unpack(format, msg) { - // implemented in go -}; - -module.exports = { - Pack: Pack, - StructsCalcSize: StructsCalcSize, - Unpack: Unpack, -}; \ No newline at end of file diff --git a/pkg/js/generated/js/libtelnet/telnet.js b/pkg/js/generated/js/libtelnet/telnet.js deleted file mode 100644 index 4217eb0eaa..0000000000 --- a/pkg/js/generated/js/libtelnet/telnet.js +++ /dev/null @@ -1,33 +0,0 @@ -/** @module telnet */ - -/** - * @class - * @classdesc TelnetClient is a minimal Telnet client for nuclei scripts - */ -class TelnetClient { - /** - * @method - * @description IsTelnet checks if a host is running a Telnet server - * @param {string} host - The host to check for Telnet server. - * @param {int} port - The port to check for Telnet server. - * @returns {IsTelnetResponse} - The response of the IsTelnet check. - * @throws {error} - The error encountered during the IsTelnet check. - * @example - * let m = require('nuclei/telnet'); - * let c = m.TelnetClient(); - * let response = c.IsTelnet('localhost', 23); - */ - IsTelnet(host, port) { - // implemented in go - }; -}; - -/** - * @typedef {object} IsTelnetResponse - * @description IsTelnetResponse is an object containing the response of the IsTelnet check. - */ -const IsTelnetResponse = {}; - -module.exports = { - TelnetClient: TelnetClient, -}; \ No newline at end of file diff --git a/pkg/js/generated/js/libvnc/vnc.js b/pkg/js/generated/js/libvnc/vnc.js deleted file mode 100644 index 4afd1eeb39..0000000000 --- a/pkg/js/generated/js/libvnc/vnc.js +++ /dev/null @@ -1,33 +0,0 @@ -/** @module vnc */ - -/** - * @class - * @classdesc VNCClient is a minimal VNC client for nuclei scripts. - */ -class VNCClient { - /** - * @method - * @description IsVNC checks if a host is running a VNC server. - * @param {string} host - The host to check. - * @param {number} port - The port to check. - * @returns {IsVNCResponse} - The response indicating if the host is running a VNC server and the banner of the VNC server. - * @throws {error} - The error encountered during the check. - * @example - * let m = require('nuclei/vnc'); - * let c = m.VNCClient(); - * let response = c.IsVNC('localhost', 5900); - */ - IsVNC(host, port) { - // implemented in go - }; -}; - -/** - * @typedef {object} IsVNCResponse - * @description IsVNCResponse is an object containing the response of the IsVNC method. - */ -const IsVNCResponse = {}; - -module.exports = { - VNCClient: VNCClient, -}; \ No newline at end of file diff --git a/pkg/js/generated/ts/bytes.ts b/pkg/js/generated/ts/bytes.ts new file mode 100755 index 0000000000..b0ed541687 --- /dev/null +++ b/pkg/js/generated/ts/bytes.ts @@ -0,0 +1,141 @@ + + +/** + * Buffer is a bytes/Uint8Array type in javascript + * @example + * ```javascript + * const bytes = require('nuclei/bytes'); + * const bytes = new bytes.Buffer(); + * ``` + * @example + * ```javascript + * const bytes = require('nuclei/bytes'); + * // optionally it can accept existing byte/Uint8Array as input + * const bytes = new bytes.Buffer([1, 2, 3]); + * ``` + */ +export class Buffer { + + + // Constructor of Buffer + constructor() {} + /** + * Write appends the given data to the buffer. + * @example + * ```javascript + * const bytes = require('nuclei/bytes'); + * const buffer = new bytes.Buffer(); + * buffer.Write([1, 2, 3]); + * ``` + */ + public Write(data: Uint8Array): Buffer { + return this; + } + + + /** + * WriteString appends the given string data to the buffer. + * @example + * ```javascript + * const bytes = require('nuclei/bytes'); + * const buffer = new bytes.Buffer(); + * buffer.WriteString('hello'); + * ``` + */ + public WriteString(data: string): Buffer { + return this; + } + + + /** + * Bytes returns the byte representation of the buffer. + * @example + * ```javascript + * const bytes = require('nuclei/bytes'); + * const buffer = new bytes.Buffer(); + * buffer.WriteString('hello'); + * log(buffer.Bytes()); + * ``` + */ + public Bytes(): Uint8Array { + return new Uint8Array(8); + } + + + /** + * String returns the string representation of the buffer. + * @example + * ```javascript + * const bytes = require('nuclei/bytes'); + * const buffer = new bytes.Buffer(); + * buffer.WriteString('hello'); + * log(buffer.String()); + * ``` + */ + public String(): string { + return ""; + } + + + /** + * Len returns the length of the buffer. + * @example + * ```javascript + * const bytes = require('nuclei/bytes'); + * const buffer = new bytes.Buffer(); + * buffer.WriteString('hello'); + * log(buffer.Len()); + * ``` + */ + public Len(): number { + return 0; + } + + + /** + * Hex returns the hex representation of the buffer. + * @example + * ```javascript + * const bytes = require('nuclei/bytes'); + * const buffer = new bytes.Buffer(); + * buffer.WriteString('hello'); + * log(buffer.Hex()); + * ``` + */ + public Hex(): string { + return ""; + } + + + /** + * Hexdump returns the hexdump representation of the buffer. + * @example + * ```javascript + * const bytes = require('nuclei/bytes'); + * const buffer = new bytes.Buffer(); + * buffer.WriteString('hello'); + * log(buffer.Hexdump()); + * ``` + */ + public Hexdump(): string { + return ""; + } + + + /** + * Pack uses structs.Pack and packs given data and appends it to the buffer. + * it packs the data according to the given format. + * @example + * ```javascript + * const bytes = require('nuclei/bytes'); + * const buffer = new bytes.Buffer(); + * buffer.Pack('I', 123); + * ``` + */ + public Pack(formatStr: string, msg: any): void { + return; + } + + +} + diff --git a/pkg/js/generated/ts/fs.ts b/pkg/js/generated/ts/fs.ts new file mode 100755 index 0000000000..234c31d61e --- /dev/null +++ b/pkg/js/generated/ts/fs.ts @@ -0,0 +1,78 @@ + + +/** + * ListDir lists itemType values within a directory + * depending on the itemType provided + * itemType can be any one of ['file','dir',”] + * @example + * ```javascript + * const fs = require('nuclei/fs'); + * // this will only return files in /tmp directory + * const files = fs.ListDir('/tmp', 'file'); + * ``` + * @example + * ```javascript + * const fs = require('nuclei/fs'); + * // this will only return directories in /tmp directory + * const dirs = fs.ListDir('/tmp', 'dir'); + * ``` + * @example + * ```javascript + * const fs = require('nuclei/fs'); + * // when no itemType is provided, it will return both files and directories + * const items = fs.ListDir('/tmp'); + * ``` + */ +export function ListDir(path: string, itemType: string): string[] | null { + return null; +} + + + +/** + * ReadFile reads file contents within permitted paths + * and returns content as byte array + * @example + * ```javascript + * const fs = require('nuclei/fs'); + * // here permitted directories are $HOME/nuclei-templates/* + * const content = fs.ReadFile('helpers/usernames.txt'); + * ``` + */ +export function ReadFile(path: string): Uint8Array | null { + return null; +} + + + +/** + * ReadFileAsString reads file contents within permitted paths + * and returns content as string + * @example + * ```javascript + * const fs = require('nuclei/fs'); + * // here permitted directories are $HOME/nuclei-templates/* + * const content = fs.ReadFileAsString('helpers/usernames.txt'); + * ``` + */ +export function ReadFileAsString(path: string): string | null { + return null; +} + + + +/** + * ReadFilesFromDir reads all files from a directory + * and returns a string array with file contents of all files + * @example + * ```javascript + * const fs = require('nuclei/fs'); + * // here permitted directories are $HOME/nuclei-templates/* + * const contents = fs.ReadFilesFromDir('helpers/ssh-keys'); + * log(contents); + * ``` + */ +export function ReadFilesFromDir(dir: string): string[] | null { + return null; +} + diff --git a/pkg/js/generated/ts/goconsole.ts b/pkg/js/generated/ts/goconsole.ts new file mode 100755 index 0000000000..f4bb707d3e --- /dev/null +++ b/pkg/js/generated/ts/goconsole.ts @@ -0,0 +1,44 @@ + + +/** + * NewGoConsolePrinter Function + */ +export function NewGoConsolePrinter(): GoConsolePrinter { + return new GoConsolePrinter(); +} + + + +/** + */ +export class GoConsolePrinter { + + + // Constructor of GoConsolePrinter + constructor() {} + /** + * Log Method + */ + public Log(msg: string): void { + return; + } + + + /** + * Warn Method + */ + public Warn(msg: string): void { + return; + } + + + /** + * Error Method + */ + public Error(msg: string): void { + return; + } + + +} + diff --git a/pkg/js/generated/ts/ikev2.ts b/pkg/js/generated/ts/ikev2.ts new file mode 100755 index 0000000000..7e8b70d78f --- /dev/null +++ b/pkg/js/generated/ts/ikev2.ts @@ -0,0 +1,124 @@ + + + +export const IKE_EXCHANGE_AUTH = 35; + + +export const IKE_EXCHANGE_CREATE_CHILD_SA = 36; + + +export const IKE_EXCHANGE_INFORMATIONAL = 37; + + +export const IKE_EXCHANGE_SA_INIT = 34; + + +export const IKE_FLAGS_InitiatorBitCheck = 0x08; + + +export const IKE_NOTIFY_NO_PROPOSAL_CHOSEN = 14; + + +export const IKE_NOTIFY_USE_TRANSPORT_MODE = 16391; + + +export const IKE_VERSION_2 = 0x20; + +/** + * IKEMessage is the IKEv2 message + * IKEv2 implements a limited subset of IKEv2 Protocol, specifically + * the IKE_NOTIFY and IKE_NONCE payloads and the IKE_SA_INIT exchange. + */ +export class IKEMessage { + + + + public InitiatorSPI?: number; + + + + public Version?: number; + + + + public ExchangeType?: number; + + + + public Flags?: number; + + + // Constructor of IKEMessage + constructor() {} + /** + * AppendPayload appends a payload to the IKE message + * payload can be any of the payloads like IKENotification, IKENonce, etc. + * @example + * ```javascript + * const ikev2 = require('nuclei/ikev2'); + * const message = new ikev2.IKEMessage(); + * const nonce = new ikev2.IKENonce(); + * nonce.NonceData = [1, 2, 3]; + * message.AppendPayload(nonce); + * ``` + */ + public AppendPayload(payload: any): void { + return; + } + + + /** + * Encode encodes the final IKE message + * @example + * ```javascript + * const ikev2 = require('nuclei/ikev2'); + * const message = new ikev2.IKEMessage(); + * const nonce = new ikev2.IKENonce(); + * nonce.NonceData = [1, 2, 3]; + * message.AppendPayload(nonce); + * log(message.Encode()); + * ``` + */ + public Encode(): Uint8Array | null { + return null; + } + + +} + + + +/** + * IKENonce is the IKEv2 Nonce payload + * this implements the IKEPayload interface + * @example + * ```javascript + * const ikev2 = require('nuclei/ikev2'); + * const nonce = new ikev2.IKENonce(); + * nonce.NonceData = [1, 2, 3]; + */ +export interface IKENonce { + + NonceData?: Uint8Array, +} + + + +/** + * IKEv2Notify is the IKEv2 Notification payload + * this implements the IKEPayload interface + * @example + * ```javascript + * const ikev2 = require('nuclei/ikev2'); + * const notify = new ikev2.IKENotification(); + * notify.NotifyMessageType = ikev2.IKE_NOTIFY_NO_PROPOSAL_CHOSEN; + * notify.NotificationData = [1, 2, 3]; + * ``` + */ +export interface IKENotification { + + NotifyMessageType?: number, + + NotificationData?: Uint8Array, +} + diff --git a/pkg/js/generated/ts/index.ts b/pkg/js/generated/ts/index.ts new file mode 100755 index 0000000000..a4175a45b9 --- /dev/null +++ b/pkg/js/generated/ts/index.ts @@ -0,0 +1,21 @@ +export * as bytes from './bytes'; +export * as fs from './fs'; +export * as goconsole from './goconsole'; +export * as ikev2 from './ikev2'; +export * as kerberos from './kerberos'; +export * as ldap from './ldap'; +export * as mssql from './mssql'; +export * as mysql from './mysql'; +export * as net from './net'; +export * as oracle from './oracle'; +export * as pop3 from './pop3'; +export * as postgres from './postgres'; +export * as rdp from './rdp'; +export * as redis from './redis'; +export * as rsync from './rsync'; +export * as smb from './smb'; +export * as smtp from './smtp'; +export * as ssh from './ssh'; +export * as structs from './structs'; +export * as telnet from './telnet'; +export * as vnc from './vnc'; diff --git a/pkg/js/generated/ts/kerberos.ts b/pkg/js/generated/ts/kerberos.ts new file mode 100755 index 0000000000..580c175a19 --- /dev/null +++ b/pkg/js/generated/ts/kerberos.ts @@ -0,0 +1,475 @@ + + +/** + * ASRepToHashcat converts an AS-REP message to a hashcat format + */ +export function ASRepToHashcat(asrep: any): string | null { + return null; +} + + + +/** + * CheckKrbError checks if the response bytes from the KDC are a KRBError. + */ +export function CheckKrbError(b: Uint8Array): Uint8Array | null { + return null; +} + + + +/** + * NewKerberosClientFromString creates a new kerberos client from a string + * by parsing krb5.conf + * @example + * ```javascript + * const kerberos = require('nuclei/kerberos'); + * const client = kerberos.NewKerberosClientFromString(` + * [libdefaults] + * default_realm = ACME.COM + * dns_lookup_kdc = true + * `); + * ``` + */ +export function NewKerberosClientFromString(cfg: string): Client | null { + return null; +} + + + +/** + * sendtokdc.go deals with actual sending and receiving responses from KDC + * SendToKDC sends a message to the KDC and returns the response. + * It first tries to send the message over TCP, and if that fails, it falls back to UDP.(and vice versa) + * @example + * ```javascript + * const kerberos = require('nuclei/kerberos'); + * const client = new kerberos.Client('acme.com'); + * const response = kerberos.SendToKDC(client, 'message'); + * ``` + */ +export function SendToKDC(kclient: Client, msg: string): string | null { + return null; +} + + + +/** + * TGStoHashcat converts a TGS to a hashcat format. + */ +export function TGStoHashcat(tgs: any, username: string): string | null { + return null; +} + + + +/** + * Known Issues: + * Hardcoded timeout in gokrb5 library + * TGT / Session Handling not exposed + * Client is kerberos client + * @example + * ```javascript + * const kerberos = require('nuclei/kerberos'); + * // if controller is empty a dns lookup for default kdc server will be performed + * const client = new kerberos.Client('acme.com', 'kdc.acme.com'); + * ``` + */ +export class Client { + + + + public Krb5Config?: Config; + + + + public Realm?: string; + + + // Constructor of Client + constructor(public domain: string, public controller?: string ) {} + + + /** + * SetConfig sets additional config for the kerberos client + * Note: as of now ip and timeout overrides are only supported + * in EnumerateUser due to fastdialer but can be extended to other methods currently + * @example + * ```javascript + * const kerberos = require('nuclei/kerberos'); + * const client = new kerberos.Client('acme.com', 'kdc.acme.com'); + * const cfg = new kerberos.Config(); + * cfg.SetIPAddress('192.168.100.22'); + * cfg.SetTimeout(5); + * client.SetConfig(cfg); + * ``` + */ + public SetConfig(cfg: Config): void { + return; + } + + + /** + * EnumerateUser and attempt to get AS-REP hash by disabling PA-FX-FAST + * @example + * ```javascript + * const kerberos = require('nuclei/kerberos'); + * const client = new kerberos.Client('acme.com', 'kdc.acme.com'); + * const resp = client.EnumerateUser('pdtm'); + * log(resp); + * ``` + */ + public EnumerateUser(username: string): EnumerateUserResponse | null { + return null; + } + + + /** + * GetServiceTicket returns a TGS for a given user, password and SPN + * @example + * ```javascript + * const kerberos = require('nuclei/kerberos'); + * const client = new kerberos.Client('acme.com', 'kdc.acme.com'); + * const resp = client.GetServiceTicket('pdtm', 'password', 'HOST/CLIENT1'); + * log(resp); + * ``` + */ + public GetServiceTicket(User: string): TGS | null { + return null; + } + + +} + + + +/** + * Config is extra configuration for the kerberos client + */ +export class Config { + + + // Constructor of Config + constructor() {} + /** + * SetIPAddress sets the IP address for the kerberos client + * @example + * ```javascript + * const kerberos = require('nuclei/kerberos'); + * const cfg = new kerberos.Config(); + * cfg.SetIPAddress('10.10.10.1'); + * ``` + */ + public SetIPAddress(ip: string): Config | null { + return null; + } + + + /** + * SetTimeout sets the RW timeout for the kerberos client + * @example + * ```javascript + * const kerberos = require('nuclei/kerberos'); + * const cfg = new kerberos.Config(); + * cfg.SetTimeout(5); + * ``` + */ + public SetTimeout(timeout: number): Config | null { + return null; + } + + +} + + + +/** + * AuthorizationDataEntry Interface + */ +export interface AuthorizationDataEntry { + + ADType?: number, + + ADData?: Uint8Array, +} + + + +/** + * BitString Interface + */ +export interface BitString { + + Bytes?: Uint8Array, + + BitLength?: number, +} + + + +/** + * BitString Interface + */ +export interface BitString { + + Bytes?: Uint8Array, + + BitLength?: number, +} + + + +/** + * Config Interface + */ +export interface Config { + + LibDefaults?: LibDefaults, + + Realms?: Realm, +} + + + +/** + * EncTicketPart Interface + */ +export interface EncTicketPart { + + CRealm?: string, + + AuthTime?: Date, + + StartTime?: Date, + + EndTime?: Date, + + RenewTill?: Date, + + Key?: EncryptionKey, + + CName?: PrincipalName, + + Transited?: TransitedEncoding, + + CAddr?: HostAddress, + + AuthorizationData?: AuthorizationDataEntry, + + Flags?: BitString, +} + + + +/** + * EncryptedData Interface + */ +export interface EncryptedData { + + Cipher?: Uint8Array, + + EType?: number, + + KVNO?: number, +} + + + +/** + * EncryptionKey Interface + */ +export interface EncryptionKey { + + KeyType?: number, + + KeyValue?: Uint8Array, +} + + + +/** + * EnumerateUserResponse is the response from EnumerateUser + */ +export interface EnumerateUserResponse { + + Valid?: boolean, + + ASREPHash?: string, + + Error?: string, +} + + + +/** + * HostAddress Interface + */ +export interface HostAddress { + + Address?: Uint8Array, + + AddrType?: number, +} + + + +/** + * LibDefaults Interface + */ +export interface LibDefaults { + + DefaultTGSEnctypes?: string[], + + DefaultTktEnctypes?: string[], + + K5LoginDirectory?: string, + + RealmTryDomains?: number, + + Canonicalize?: boolean, + + K5LoginAuthoritative?: boolean, + + NoAddresses?: boolean, + + SafeChecksumType?: number, + + DefaultClientKeytabName?: string, + + DNSLookupKDC?: boolean, + + IgnoreAcceptorHostname?: boolean, + + Proxiable?: boolean, + + /** + * time in nanoseconds + */ + + TicketLifetime?: number, + + DefaultKeytabName?: string, + + DefaultTktEnctypeIDs?: number[], + + Forwardable?: boolean, + + PermittedEnctypeIDs?: number[], + + PreferredPreauthTypes?: number[], + + UDPPreferenceLimit?: number, + + VerifyAPReqNofail?: boolean, + + /** + * time in nanoseconds + */ + + Clockskew?: number, + + RDNS?: boolean, + + DNSCanonicalizeHostname?: boolean, + + KDCTimeSync?: number, + + PermittedEnctypes?: string[], + + DefaultRealm?: string, + + /** + * time in nanoseconds + */ + + RenewLifetime?: number, + + CCacheType?: number, + + DefaultTGSEnctypeIDs?: number[], + + DNSLookupRealm?: boolean, + + ExtraAddresses?: Uint8Array, + + AllowWeakCrypto?: boolean, + + KDCDefaultOptions?: BitString, +} + + + +/** + * PrincipalName Interface + */ +export interface PrincipalName { + + NameType?: number, + + NameString?: string[], +} + + + +/** + * Realm Interface + */ +export interface Realm { + + DefaultDomain?: string, + + KDC?: string[], + + KPasswdServer?: string[], + + MasterKDC?: string[], + + Realm?: string, + + AdminServer?: string[], +} + + + +/** + * TGS is the response from GetServiceTicket + */ +export interface TGS { + + Ticket?: Ticket, + + Hash?: string, + + ErrMsg?: string, +} + + + +/** + * Ticket Interface + */ +export interface Ticket { + + TktVNO?: number, + + Realm?: string, + + SName?: PrincipalName, + + EncPart?: EncryptedData, + + DecryptedEncPart?: EncTicketPart, +} + + + +/** + * TransitedEncoding Interface + */ +export interface TransitedEncoding { + + TRType?: number, + + Contents?: Uint8Array, +} + diff --git a/pkg/js/generated/ts/ldap.ts b/pkg/js/generated/ts/ldap.ts new file mode 100755 index 0000000000..241936deac --- /dev/null +++ b/pkg/js/generated/ts/ldap.ts @@ -0,0 +1,578 @@ + + +/** The user account is disabled. */ +export const FilterAccountDisabled = "(userAccountControl:1.2.840.113556.1.4.803:=2)"; + +/** The user account is enabled. */ +export const FilterAccountEnabled = "(!(userAccountControl:1.2.840.113556.1.4.803:=2))"; + +/** The user can send an encrypted password. */ +export const FilterCanSendEncryptedPassword = "(userAccountControl:1.2.840.113556.1.4.803:=128)"; + +/** Represents the password, which should never expire on the account. */ +export const FilterDontExpirePassword = "(userAccountControl:1.2.840.113556.1.4.803:=65536)"; + +/** This account doesn't require Kerberos pre-authentication for logging on. */ +export const FilterDontRequirePreauth = "(userAccountControl:1.2.840.113556.1.4.803:=4194304)"; + +/** The object has a service principal name. */ +export const FilterHasServicePrincipalName = "(servicePrincipalName=*)"; + +/** The home folder is required. */ +export const FilterHomedirRequired = "(userAccountControl:1.2.840.113556.1.4.803:=8)"; + +/** It's a permit to trust an account for a system domain that trusts other domains. */ +export const FilterInterdomainTrustAccount = "(userAccountControl:1.2.840.113556.1.4.803:=2048)"; + +/** The object is an admin. */ +export const FilterIsAdmin = "(adminCount=1)"; + +/** The object is a computer. */ +export const FilterIsComputer = "(objectCategory=computer)"; + +/** It's an account for users whose primary account is in another domain. */ +export const FilterIsDuplicateAccount = "(userAccountControl:1.2.840.113556.1.4.803:=256)"; + +/** The object is a group. */ +export const FilterIsGroup = "(objectCategory=group)"; + +/** It's a default account type that represents a typical user. */ +export const FilterIsNormalAccount = "(userAccountControl:1.2.840.113556.1.4.803:=512)"; + +/** The object is a person. */ +export const FilterIsPerson = "(objectCategory=person)"; + +/** The user is locked out. */ +export const FilterLockout = "(userAccountControl:1.2.840.113556.1.4.803:=16)"; + +/** The logon script will be run. */ +export const FilterLogonScript = "(userAccountControl:1.2.840.113556.1.4.803:=1)"; + +/** It's an MNS logon account. */ +export const FilterMnsLogonAccount = "(userAccountControl:1.2.840.113556.1.4.803:=131072)"; + +/** When this flag is set, the security context of the user isn't delegated to a service even if the service account is set as trusted for Kerberos delegation. */ +export const FilterNotDelegated = "(userAccountControl:1.2.840.113556.1.4.803:=1048576)"; + +/** The account is a read-only domain controller (RODC). */ +export const FilterPartialSecretsAccount = "(userAccountControl:1.2.840.113556.1.4.803:=67108864)"; + +/** The user can't change the password. */ +export const FilterPasswordCantChange = "(userAccountControl:1.2.840.113556.1.4.803:=64)"; + +/** The user's password has expired. */ +export const FilterPasswordExpired = "(userAccountControl:1.2.840.113556.1.4.803:=8388608)"; + +/** No password is required. */ +export const FilterPasswordNotRequired = "(userAccountControl:1.2.840.113556.1.4.803:=32)"; + +/** It's a computer account for a domain controller that is a member of this domain. */ +export const FilterServerTrustAccount = "(userAccountControl:1.2.840.113556.1.4.803:=8192)"; + +/** When this flag is set, it forces the user to log on by using a smart card. */ +export const FilterSmartCardRequired = "(userAccountControl:1.2.840.113556.1.4.803:=262144)"; + +/** When this flag is set, the service account (the user or computer account) under which a service runs is trusted for Kerberos delegation. */ +export const FilterTrustedForDelegation = "(userAccountControl:1.2.840.113556.1.4.803:=524288)"; + +/** The account is enabled for delegation. */ +export const FilterTrustedToAuthForDelegation = "(userAccountControl:1.2.840.113556.1.4.803:=16777216)"; + +/** Restrict this principal to use only Data Encryption Standard (DES) encryption types for keys. */ +export const FilterUseDesKeyOnly = "(userAccountControl:1.2.840.113556.1.4.803:=2097152)"; + +/** It's a computer account for a computer that is running old Windows builds. */ +export const FilterWorkstationTrustAccount = "(userAccountControl:1.2.840.113556.1.4.803:=4096)"; + +/** + * DecodeADTimestamp decodes an Active Directory timestamp + * @example + * ```javascript + * const ldap = require('nuclei/ldap'); + * const timestamp = ldap.DecodeADTimestamp('132036744000000000'); + * log(timestamp); + * ``` + */ +export function DecodeADTimestamp(timestamp: string): string { + return ""; +} + + + +/** + * DecodeSID decodes a SID string + * @example + * ```javascript + * const ldap = require('nuclei/ldap'); + * const sid = ldap.DecodeSID('S-1-5-21-3623811015-3361044348-30300820-1013'); + * log(sid); + * ``` + */ +export function DecodeSID(s: string): string { + return ""; +} + + + +/** + * DecodeZuluTimestamp decodes a Zulu timestamp + * @example + * ```javascript + * const ldap = require('nuclei/ldap'); + * const timestamp = ldap.DecodeZuluTimestamp('2021-08-25T10:00:00Z'); + * log(timestamp); + * ``` + */ +export function DecodeZuluTimestamp(timestamp: string): string { + return ""; +} + + + +/** + * JoinFilters joins multiple filters into a single filter + * @example + * ```javascript + * const ldap = require('nuclei/ldap'); + * const filter = ldap.JoinFilters(ldap.FilterIsPerson, ldap.FilterAccountEnabled); + * ``` + */ +export function JoinFilters(filters: any): string { + return ""; +} + + + +/** + * NegativeFilter returns a negative filter for a given filter + * @example + * ```javascript + * const ldap = require('nuclei/ldap'); + * const filter = ldap.NegativeFilter(ldap.FilterIsPerson); + * ``` + */ +export function NegativeFilter(filter: string): string { + return ""; +} + + + +/** + * Client is a client for ldap protocol in nuclei + * @example + * ```javascript + * const ldap = require('nuclei/ldap'); + * // here ldap.example.com is the ldap server and acme.com is the realm + * const client = new ldap.Client('ldap://ldap.example.com', 'acme.com'); + * ``` + * @example + * ```javascript + * const ldap = require('nuclei/ldap'); + * const cfg = new ldap.Config(); + * cfg.Timeout = 10; + * cfg.ServerName = 'ldap.internal.acme.com'; + * // optional config can be passed as third argument + * const client = new ldap.Client('ldap://ldap.example.com', 'acme.com', cfg); + * ``` + */ +export class Client { + + + + public Host?: string; + + + + public Port?: number; + + + + public Realm?: string; + + + + public BaseDN?: string; + + + // Constructor of Client + constructor(public ldapUrl: string, public realm: string, public config?: Config ) {} + + + /** + * FindADObjects finds AD objects based on a filter + * and returns them as a list of ADObject + * @example + * ```javascript + * const ldap = require('nuclei/ldap'); + * const client = new ldap.Client('ldap://ldap.example.com', 'acme.com'); + * const users = client.FindADObjects(ldap.FilterIsPerson); + * log(to_json(users)); + * ``` + */ + public FindADObjects(filter: string): ADObject[] { + return []; + } + + + /** + * GetADUsers returns all AD users + * using FilterIsPerson filter query + * @example + * ```javascript + * const ldap = require('nuclei/ldap'); + * const client = new ldap.Client('ldap://ldap.example.com', 'acme.com'); + * const users = client.GetADUsers(); + * log(to_json(users)); + * ``` + */ + public GetADUsers(): ADObject[] { + return []; + } + + + /** + * GetADActiveUsers returns all AD users + * using FilterIsPerson and FilterAccountEnabled filter query + * @example + * ```javascript + * const ldap = require('nuclei/ldap'); + * const client = new ldap.Client('ldap://ldap.example.com', 'acme.com'); + * const users = client.GetADActiveUsers(); + * log(to_json(users)); + * ``` + */ + public GetADActiveUsers(): ADObject[] { + return []; + } + + + /** + * GetAdUserWithNeverExpiringPasswords returns all AD users + * using FilterIsPerson and FilterDontExpirePassword filter query + * @example + * ```javascript + * const ldap = require('nuclei/ldap'); + * const client = new ldap.Client('ldap://ldap.example.com', 'acme.com'); + * const users = client.GetADUserWithNeverExpiringPasswords(); + * log(to_json(users)); + * ``` + */ + public GetADUserWithNeverExpiringPasswords(): ADObject[] { + return []; + } + + + /** + * GetADUserTrustedForDelegation returns all AD users that are trusted for delegation + * using FilterIsPerson and FilterTrustedForDelegation filter query + * @example + * ```javascript + * const ldap = require('nuclei/ldap'); + * const client = new ldap.Client('ldap://ldap.example.com', 'acme.com'); + * const users = client.GetADUserTrustedForDelegation(); + * log(to_json(users)); + * ``` + */ + public GetADUserTrustedForDelegation(): ADObject[] { + return []; + } + + + /** + * GetADUserWithPasswordNotRequired returns all AD users that do not require a password + * using FilterIsPerson and FilterPasswordNotRequired filter query + * @example + * ```javascript + * const ldap = require('nuclei/ldap'); + * const client = new ldap.Client('ldap://ldap.example.com', 'acme.com'); + * const users = client.GetADUserWithPasswordNotRequired(); + * log(to_json(users)); + * ``` + */ + public GetADUserWithPasswordNotRequired(): ADObject[] { + return []; + } + + + /** + * GetADGroups returns all AD groups + * using FilterIsGroup filter query + * @example + * ```javascript + * const ldap = require('nuclei/ldap'); + * const client = new ldap.Client('ldap://ldap.example.com', 'acme.com'); + * const groups = client.GetADGroups(); + * log(to_json(groups)); + * ``` + */ + public GetADGroups(): ADObject[] { + return []; + } + + + /** + * GetADDCList returns all AD domain controllers + * using FilterIsComputer, FilterAccountEnabled and FilterServerTrustAccount filter query + * @example + * ```javascript + * const ldap = require('nuclei/ldap'); + * const client = new ldap.Client('ldap://ldap.example.com', 'acme.com'); + * const dcs = client.GetADDCList(); + * log(to_json(dcs)); + * ``` + */ + public GetADDCList(): ADObject[] { + return []; + } + + + /** + * GetADAdmins returns all AD admins + * using FilterIsPerson, FilterAccountEnabled and FilterIsAdmin filter query + * @example + * ```javascript + * const ldap = require('nuclei/ldap'); + * const client = new ldap.Client('ldap://ldap.example.com', 'acme.com'); + * const admins = client.GetADAdmins(); + * log(to_json(admins)); + * ``` + */ + public GetADAdmins(): ADObject[] { + return []; + } + + + /** + * GetADUserKerberoastable returns all AD users that are kerberoastable + * using FilterIsPerson, FilterAccountEnabled and FilterHasServicePrincipalName filter query + * @example + * ```javascript + * const ldap = require('nuclei/ldap'); + * const client = new ldap.Client('ldap://ldap.example.com', 'acme.com'); + * const kerberoastable = client.GetADUserKerberoastable(); + * log(to_json(kerberoastable)); + * ``` + */ + public GetADUserKerberoastable(): ADObject[] { + return []; + } + + + /** + * GetADDomainSID returns the SID of the AD domain + * @example + * ```javascript + * const ldap = require('nuclei/ldap'); + * const client = new ldap.Client('ldap://ldap.example.com', 'acme.com'); + * const domainSID = client.GetADDomainSID(); + * log(domainSID); + * ``` + */ + public GetADDomainSID(): string { + return ""; + } + + + /** + * Authenticate authenticates with the ldap server using the given username and password + * performs NTLMBind first and then Bind/UnauthenticatedBind if NTLMBind fails + * @example + * ```javascript + * const ldap = require('nuclei/ldap'); + * const client = new ldap.Client('ldap://ldap.example.com', 'acme.com'); + * client.Authenticate('user', 'password'); + * ``` + */ + public Authenticate(username: string): void { + return; + } + + + /** + * AuthenticateWithNTLMHash authenticates with the ldap server using the given username and NTLM hash + * @example + * ```javascript + * const ldap = require('nuclei/ldap'); + * const client = new ldap.Client('ldap://ldap.example.com', 'acme.com'); + * client.AuthenticateWithNTLMHash('pdtm', 'hash'); + * ``` + */ + public AuthenticateWithNTLMHash(username: string): void { + return; + } + + + /** + * Search accepts whatever filter and returns a list of maps having provided attributes + * as keys and associated values mirroring the ones returned by ldap + * @example + * ```javascript + * const ldap = require('nuclei/ldap'); + * const client = new ldap.Client('ldap://ldap.example.com', 'acme.com'); + * const results = client.Search('(objectClass=*)', 'cn', 'mail'); + * ``` + */ + public Search(filter: string, attributes: any): Record[] { + return []; + } + + + /** + * AdvancedSearch accepts all values of search request type and return Ldap Entry + * its up to user to handle the response + * @example + * ```javascript + * const ldap = require('nuclei/ldap'); + * const client = new ldap.Client('ldap://ldap.example.com', 'acme.com'); + * const results = client.AdvancedSearch(ldap.ScopeWholeSubtree, ldap.NeverDerefAliases, 0, 0, false, '(objectClass=*)', ['cn', 'mail'], []); + * ``` + */ + public AdvancedSearch(Scope: number, TypesOnly: boolean, Filter: string, Attributes: string[], Controls: any): SearchResult | null { + return null; + } + + + /** + * CollectLdapMetadata collects metadata from ldap server. + * @example + * ```javascript + * const ldap = require('nuclei/ldap'); + * const client = new ldap.Client('ldap://ldap.example.com', 'acme.com'); + * const metadata = client.CollectMetadata(); + * log(to_json(metadata)); + * ``` + */ + public CollectMetadata(): Metadata | null { + return null; + } + + + /** + * close the ldap connection + * @example + * ```javascript + * const ldap = require('nuclei/ldap'); + * const client = new ldap.Client('ldap://ldap.example.com', 'acme.com'); + * client.Close(); + * ``` + */ + public Close(): void { + return; + } + + +} + + + +/** + * ADObject represents an Active Directory object + * @example + * ```javascript + * const ldap = require('nuclei/ldap'); + * const client = new ldap.Client('ldap://ldap.example.com', 'acme.com'); + * const users = client.GetADUsers(); + * log(to_json(users)); + */ +export interface ADObject { + + DistinguishedName?: string, + + SAMAccountName?: string, + + PWDLastSet?: string, + + LastLogon?: string, + + MemberOf?: string[], + + ServicePrincipalName?: string[], +} + + + +/** + * Config is extra configuration for the ldap client + * @example + * ```javascript + * const ldap = require('nuclei/ldap'); + * const cfg = new ldap.Config(); + * cfg.Timeout = 10; + * cfg.ServerName = 'ldap.internal.acme.com'; + * cfg.Upgrade = true; // upgrade to tls + * ``` + */ +export interface Config { + + /** + * Timeout is the timeout for the ldap client in seconds + */ + + Timeout?: number, + + ServerName?: string, + + Upgrade?: boolean, +} + + + +/** + * Entry Interface + */ +export interface Entry { + + DN?: string, + + Attributes?: EntryAttribute, +} + + + +/** + * EntryAttribute Interface + */ +export interface EntryAttribute { + + Name?: string, + + Values?: string[], + + ByteValues?: Uint8Array, +} + + + +/** + * Metadata is the metadata for ldap server. + * this is returned by CollectMetadata method + */ +export interface Metadata { + + BaseDN?: string, + + Domain?: string, + + DefaultNamingContext?: string, + + DomainFunctionality?: string, + + ForestFunctionality?: string, + + DomainControllerFunctionality?: string, + + DnsHostName?: string, +} + + + +/** + * SearchResult Interface + */ +export interface SearchResult { + + Referrals?: string[], + + Entries?: Entry, +} + diff --git a/pkg/js/generated/ts/mssql.ts b/pkg/js/generated/ts/mssql.ts new file mode 100755 index 0000000000..0e9f28f201 --- /dev/null +++ b/pkg/js/generated/ts/mssql.ts @@ -0,0 +1,67 @@ + + +/** + * Client is a client for MS SQL database. + * Internally client uses denisenkom/go-mssqldb driver. + * @example + * ```javascript + * const mssql = require('nuclei/mssql'); + * const client = new mssql.Client(); + * ``` + */ +export class MSSQLClient { + + + // Constructor of MSSQLClient + constructor() {} + /** + * Connect connects to MS SQL database using given credentials. + * If connection is successful, it returns true. + * If connection is unsuccessful, it returns false and error. + * The connection is closed after the function returns. + * @example + * ```javascript + * const mssql = require('nuclei/mssql'); + * const client = new mssql.Client(); + * const connected = client.Connect('acme.com', 1433, 'username', 'password'); + * ``` + */ + public Connect(host: string, port: number, username: string): boolean | null { + return null; + } + + + /** + * ConnectWithDB connects to MS SQL database using given credentials and database name. + * If connection is successful, it returns true. + * If connection is unsuccessful, it returns false and error. + * The connection is closed after the function returns. + * @example + * ```javascript + * const mssql = require('nuclei/mssql'); + * const client = new mssql.Client(); + * const connected = client.ConnectWithDB('acme.com', 1433, 'username', 'password', 'master'); + * ``` + */ + public ConnectWithDB(host: string, port: number, username: string): boolean | null { + return null; + } + + + /** + * IsMssql checks if the given host is running MS SQL database. + * If the host is running MS SQL database, it returns true. + * If the host is not running MS SQL database, it returns false. + * @example + * ```javascript + * const mssql = require('nuclei/mssql'); + * const isMssql = mssql.IsMssql('acme.com', 1433); + * ``` + */ + public IsMssql(host: string, port: number): boolean | null { + return null; + } + + +} + diff --git a/pkg/js/generated/ts/mysql.ts b/pkg/js/generated/ts/mysql.ts new file mode 100755 index 0000000000..d8fabb13e8 --- /dev/null +++ b/pkg/js/generated/ts/mysql.ts @@ -0,0 +1,230 @@ + + +/** + * BuildDSN builds a MySQL data source name (DSN) from the given options. + * @example + * ```javascript + * const mysql = require('nuclei/mysql'); + * const options = new mysql.MySQLOptions(); + * options.Host = 'acme.com'; + * options.Port = 3306; + * const dsn = mysql.BuildDSN(options); + * ``` + */ +export function BuildDSN(opts: MySQLOptions): string | null { + return null; +} + + + +/** + * MySQLClient is a client for MySQL database. + * Internally client uses go-sql-driver/mysql driver. + * @example + * ```javascript + * const mysql = require('nuclei/mysql'); + * const client = new mysql.Client(); + * ``` + */ +export class MySQLClient { + + + // Constructor of MySQLClient + constructor() {} + /** + * IsMySQL checks if the given host is running MySQL database. + * If the host is running MySQL database, it returns true. + * If the host is not running MySQL database, it returns false. + * @example + * ```javascript + * const mysql = require('nuclei/mysql'); + * const isMySQL = mysql.IsMySQL('acme.com', 3306); + * ``` + */ + public IsMySQL(host: string, port: number): boolean | null { + return null; + } + + + /** + * Connect connects to MySQL database using given credentials. + * If connection is successful, it returns true. + * If connection is unsuccessful, it returns false and error. + * The connection is closed after the function returns. + * @example + * ```javascript + * const mysql = require('nuclei/mysql'); + * const client = new mysql.Client(); + * const connected = client.Connect('acme.com', 3306, 'username', 'password'); + * ``` + */ + public Connect(host: string, port: number, username: string): boolean | null { + return null; + } + + + /** + * returns MySQLInfo when fingerpint is successful + * @example + * ```javascript + * const mysql = require('nuclei/mysql'); + * const info = mysql.FingerprintMySQL('acme.com', 3306); + * log(to_json(info)); + * ``` + */ + public FingerprintMySQL(host: string, port: number): MySQLInfo | null { + return null; + } + + + /** + * ConnectWithDSN connects to MySQL database using given DSN. + * we override mysql dialer with fastdialer so it respects network policy + * If connection is successful, it returns true. + * @example + * ```javascript + * const mysql = require('nuclei/mysql'); + * const client = new mysql.Client(); + * const connected = client.ConnectWithDSN('username:password@tcp(acme.com:3306)/'); + * ``` + */ + public ConnectWithDSN(dsn: string): boolean | null { + return null; + } + + + /** + * ExecuteQueryWithOpts connects to Mysql database using given credentials + * and executes a query on the db. + * @example + * ```javascript + * const mysql = require('nuclei/mysql'); + * const options = new mysql.MySQLOptions(); + * options.Host = 'acme.com'; + * options.Port = 3306; + * const result = mysql.ExecuteQueryWithOpts(options, 'SELECT * FROM users'); + * log(to_json(result)); + * ``` + */ + public ExecuteQueryWithOpts(opts: MySQLOptions, query: string): SQLResult | null | null { + return null; + } + + + /** + * ExecuteQuery connects to Mysql database using given credentials + * and executes a query on the db. + * @example + * ```javascript + * const mysql = require('nuclei/mysql'); + * const result = mysql.ExecuteQuery('acme.com', 3306, 'username', 'password', 'SELECT * FROM users'); + * log(to_json(result)); + * ``` + */ + public ExecuteQuery(host: string, port: number, username: string): SQLResult | null | null { + return null; + } + + + /** + * ExecuteQuery connects to Mysql database using given credentials + * and executes a query on the db. + * @example + * ```javascript + * const mysql = require('nuclei/mysql'); + * const result = mysql.ExecuteQueryOnDB('acme.com', 3306, 'username', 'password', 'dbname', 'SELECT * FROM users'); + * log(to_json(result)); + * ``` + */ + public ExecuteQueryOnDB(host: string, port: number, username: string): SQLResult | null | null { + return null; + } + + +} + + + +/** + * MySQLInfo contains information about MySQL server. + * this is returned when fingerprint is successful + */ +export interface MySQLInfo { + + Host?: string, + + IP?: string, + + Port?: number, + + Protocol?: string, + + TLS?: boolean, + + Transport?: string, + + Version?: string, + + Debug?: ServiceMySQL, + + Raw?: string, +} + + + +/** + * MySQLOptions defines the data source name (DSN) options required to connect to a MySQL database. + * along with other options like Timeout etc + * @example + * ```javascript + * const mysql = require('nuclei/mysql'); + * const options = new mysql.MySQLOptions(); + * options.Host = 'acme.com'; + * options.Port = 3306; + * ``` + */ +export interface MySQLOptions { + + Host?: string, + + Port?: number, + + Protocol?: string, + + Username?: string, + + Password?: string, + + DbName?: string, + + RawQuery?: string, + + Timeout?: number, +} + + + +/** + * SQLResult Interface + */ +export interface SQLResult { + + Count?: number, + + Columns?: string[], +} + + + +/** + * ServiceMySQL Interface + */ +export interface ServiceMySQL { + + PacketType?: string, + + ErrorMessage?: string, + + ErrorCode?: number, +} + diff --git a/pkg/js/generated/ts/net.ts b/pkg/js/generated/ts/net.ts new file mode 100755 index 0000000000..2a601ae780 --- /dev/null +++ b/pkg/js/generated/ts/net.ts @@ -0,0 +1,183 @@ + + +/** + * Open opens a new connection to the address with a timeout. + * supported protocols: tcp, udp + * @example + * ```javascript + * const net = require('nuclei/net'); + * const conn = net.Open('tcp', 'acme.com:80'); + * ``` + */ +export function Open(protocol: string): NetConn | null { + return null; +} + + + +/** + * Open opens a new connection to the address with a timeout. + * supported protocols: tcp, udp + * @example + * ```javascript + * const net = require('nuclei/net'); + * const conn = net.OpenTLS('tcp', 'acme.com:443'); + * ``` + */ +export function OpenTLS(protocol: string): NetConn | null { + return null; +} + + + +/** + * NetConn is a connection to a remote host. + * this is returned/create by Open and OpenTLS functions. + * @example + * ```javascript + * const net = require('nuclei/net'); + * const conn = net.Open('tcp', 'acme.com:80'); + * ``` + */ +export class NetConn { + + + // Constructor of NetConn + constructor() {} + /** + * Close closes the connection. + * @example + * ```javascript + * const net = require('nuclei/net'); + * const conn = net.Open('tcp', 'acme.com:80'); + * conn.Close(); + * ``` + */ + public Close(): void { + return; + } + + + /** + * SetTimeout sets read/write timeout for the connection (in seconds). + * @example + * ```javascript + * const net = require('nuclei/net'); + * const conn = net.Open('tcp', 'acme.com:80'); + * conn.SetTimeout(10); + * ``` + */ + public SetTimeout(value: number): void { + return; + } + + + /** + * SendArray sends array data to connection + * @example + * ```javascript + * const net = require('nuclei/net'); + * const conn = net.Open('tcp', 'acme.com:80'); + * conn.SendArray(['hello', 'world']); + * ``` + */ + public SendArray(data: any): void { + return; + } + + + /** + * SendHex sends hex data to connection + * @example + * ```javascript + * const net = require('nuclei/net'); + * const conn = net.Open('tcp', 'acme.com:80'); + * conn.SendHex('68656c6c6f'); + * ``` + */ + public SendHex(data: string): void { + return; + } + + + /** + * Send sends data to the connection with a timeout. + * @example + * ```javascript + * const net = require('nuclei/net'); + * const conn = net.Open('tcp', 'acme.com:80'); + * conn.Send('hello'); + * ``` + */ + public Send(data: string): void { + return; + } + + + /** + * Recv receives data from the connection with a timeout. + * If N is 0, it will read all data sent by the server with 8MB limit. + * it tries to read until N bytes or timeout is reached. + * @example + * ```javascript + * const net = require('nuclei/net'); + * const conn = net.Open('tcp', 'acme.com:80'); + * const data = conn.Recv(1024); + * ``` + */ + public Recv(N: number): Uint8Array | null { + return null; + } + + + /** + * RecvPartial is similar to Recv but it does not perform full read instead + * it creates a buffer of N bytes and returns whatever is returned by the connection + * this is usually used when fingerprinting services to get initial bytes from the server. + * @example + * ```javascript + * const net = require('nuclei/net'); + * const conn = net.Open('tcp', 'acme.com:80'); + * const data = conn.RecvPartial(1024); + * log(`Received ${data.length} bytes from the server`) + * ``` + */ + public RecvPartial(N: number): Uint8Array | null { + return null; + } + + + /** + * RecvString receives data from the connection with a timeout + * output is returned as a string. + * If N is 0, it will read all data sent by the server with 8MB limit. + * @example + * ```javascript + * const net = require('nuclei/net'); + * const conn = net.Open('tcp', 'acme.com:80'); + * const data = conn.RecvString(1024); + * ``` + */ + public RecvString(N: number): string | null { + return null; + } + + + /** + * RecvHex receives data from the connection with a timeout + * in hex format. + * If N is 0,it will read all data sent by the server with 8MB limit. + * @example + * ```javascript + * const net = require('nuclei/net'); + * const conn = net.Open('tcp', 'acme.com:80'); + * const data = conn.RecvHex(1024); + * ``` + */ + public RecvHex(N: number): string | null { + return null; + } + + +} + diff --git a/pkg/js/generated/ts/oracle.ts b/pkg/js/generated/ts/oracle.ts new file mode 100755 index 0000000000..fa895a976f --- /dev/null +++ b/pkg/js/generated/ts/oracle.ts @@ -0,0 +1,49 @@ + + +/** + * OracleClient is a minimal Oracle client for nuclei scripts. + * @example + * ```javascript + * const oracle = require('nuclei/oracle'); + * const client = new oracle.Client(); + * ``` + */ +export class OracleClient { + + + // Constructor of OracleClient + constructor() {} + /** + * IsOracle checks if a host is running an Oracle server + * @example + * ```javascript + * const oracle = require('nuclei/oracle'); + * const isOracle = oracle.IsOracle('acme.com', 1521); + * log(toJSON(isOracle)); + * ``` + */ + public IsOracle(host: string, port: number): IsOracleResponse | null { + return null; + } + + +} + + + +/** + * IsOracleResponse is the response from the IsOracle function. + * this is returned by IsOracle function. + * @example + * ```javascript + * const oracle = require('nuclei/oracle'); + * const isOracle = oracle.IsOracle('acme.com', 1521); + * ``` + */ +export interface IsOracleResponse { + + IsOracle?: boolean, + + Banner?: string, +} + diff --git a/pkg/js/generated/ts/pop3.ts b/pkg/js/generated/ts/pop3.ts new file mode 100755 index 0000000000..c7bc2cf6c1 --- /dev/null +++ b/pkg/js/generated/ts/pop3.ts @@ -0,0 +1,50 @@ + + +/** + * Pop3Client is a minimal POP3 client for nuclei scripts. + * @example + * ```javascript + * const pop3 = require('nuclei/pop3'); + * const client = new pop3.Client(); + * ``` + */ +export class Pop3Client { + + + // Constructor of Pop3Client + constructor() {} + /** + * IsPOP3 checks if a host is running a POP3 server. + * @example + * ```javascript + * const pop3 = require('nuclei/pop3'); + * const isPOP3 = pop3.IsPOP3('acme.com', 110); + * log(toJSON(isPOP3)); + * ``` + */ + public IsPOP3(host: string, port: number): IsPOP3Response | null { + return null; + } + + +} + + + +/** + * IsPOP3Response is the response from the IsPOP3 function. + * this is returned by IsPOP3 function. + * @example + * ```javascript + * const pop3 = require('nuclei/pop3'); + * const isPOP3 = pop3.IsPOP3('acme.com', 110); + * log(toJSON(isPOP3)); + * ``` + */ +export interface IsPOP3Response { + + IsPOP3?: boolean, + + Banner?: string, +} + diff --git a/pkg/js/generated/ts/postgres.ts b/pkg/js/generated/ts/postgres.ts new file mode 100755 index 0000000000..dff06a9d0d --- /dev/null +++ b/pkg/js/generated/ts/postgres.ts @@ -0,0 +1,96 @@ + + +/** + * PGClient is a client for Postgres database. + * Internally client uses go-pg/pg driver. + * @example + * ```javascript + * const postgres = require('nuclei/postgres'); + * const client = new postgres.Client(); + * ``` + */ +export class PGClient { + + + // Constructor of PGClient + constructor() {} + /** + * IsPostgres checks if the given host and port are running Postgres database. + * If connection is successful, it returns true. + * If connection is unsuccessful, it returns false and error. + * @example + * ```javascript + * const postgres = require('nuclei/postgres'); + * const isPostgres = postgres.IsPostgres('acme.com', 5432); + * ``` + */ + public IsPostgres(host: string, port: number): boolean | null { + return null; + } + + + /** + * Connect connects to Postgres database using given credentials. + * If connection is successful, it returns true. + * If connection is unsuccessful, it returns false and error. + * The connection is closed after the function returns. + * @example + * ```javascript + * const postgres = require('nuclei/postgres'); + * const client = new postgres.Client(); + * const connected = client.Connect('acme.com', 5432, 'username', 'password'); + * ``` + */ + public Connect(host: string, port: number, username: string): boolean | null { + return null; + } + + + /** + * ExecuteQuery connects to Postgres database using given credentials and database name. + * and executes a query on the db. + * If connection is successful, it returns the result of the query. + * @example + * ```javascript + * const postgres = require('nuclei/postgres'); + * const client = new postgres.Client(); + * const result = client.ExecuteQuery('acme.com', 5432, 'username', 'password', 'dbname', 'select * from users'); + * log(to_json(result)); + * ``` + */ + public ExecuteQuery(host: string, port: number, username: string): SQLResult | null | null { + return null; + } + + + /** + * ConnectWithDB connects to Postgres database using given credentials and database name. + * If connection is successful, it returns true. + * If connection is unsuccessful, it returns false and error. + * The connection is closed after the function returns. + * @example + * ```javascript + * const postgres = require('nuclei/postgres'); + * const client = new postgres.Client(); + * const connected = client.ConnectWithDB('acme.com', 5432, 'username', 'password', 'dbname'); + * ``` + */ + public ConnectWithDB(host: string, port: number, username: string): boolean | null { + return null; + } + + +} + + + +/** + * SQLResult Interface + */ +export interface SQLResult { + + Count?: number, + + Columns?: string[], +} + diff --git a/pkg/js/generated/ts/rdp.ts b/pkg/js/generated/ts/rdp.ts new file mode 100755 index 0000000000..2c1ab13747 --- /dev/null +++ b/pkg/js/generated/ts/rdp.ts @@ -0,0 +1,112 @@ + + +/** + * RDPClient is a minimal RDP client for nuclei scripts. + * @example + * ```javascript + * const rdp = require('nuclei/rdp'); + * const client = new rdp.Client(); + * ``` + */ +export class RDPClient { + + + // Constructor of RDPClient + constructor() {} + /** + * IsRDP checks if the given host and port are running rdp server. + * If connection is successful, it returns true. + * If connection is unsuccessful, it returns false and error. + * The Name of the OS is also returned if the connection is successful. + * @example + * ```javascript + * const rdp = require('nuclei/rdp'); + * const isRDP = rdp.IsRDP('acme.com', 3389); + * log(toJSON(isRDP)); + * ``` + */ + public IsRDP(host: string, port: number): IsRDPResponse | null { + return null; + } + + + /** + * CheckRDPAuth checks if the given host and port are running rdp server + * with authentication and returns their metadata. + * If connection is successful, it returns true. + * @example + * ```javascript + * const rdp = require('nuclei/rdp'); + * const checkRDPAuth = rdp.CheckRDPAuth('acme.com', 3389); + * log(toJSON(checkRDPAuth)); + * ``` + */ + public CheckRDPAuth(host: string, port: number): CheckRDPAuthResponse | null { + return null; + } + + +} + + + +/** + * CheckRDPAuthResponse is the response from the CheckRDPAuth function. + * this is returned by CheckRDPAuth function. + * @example + * ```javascript + * const rdp = require('nuclei/rdp'); + * const checkRDPAuth = rdp.CheckRDPAuth('acme.com', 3389); + * log(toJSON(checkRDPAuth)); + * ``` + */ +export interface CheckRDPAuthResponse { + + PluginInfo?: ServiceRDP, + + Auth?: boolean, +} + + + +/** + * IsRDPResponse is the response from the IsRDP function. + * this is returned by IsRDP function. + * @example + * ```javascript + * const rdp = require('nuclei/rdp'); + * const isRDP = rdp.IsRDP('acme.com', 3389); + * log(toJSON(isRDP)); + * ``` + */ +export interface IsRDPResponse { + + IsRDP?: boolean, + + OS?: string, +} + + + +/** + * ServiceRDP Interface + */ +export interface ServiceRDP { + + NetBIOSComputerName?: string, + + NetBIOSDomainName?: string, + + DNSComputerName?: string, + + DNSDomainName?: string, + + ForestName?: string, + + OSFingerprint?: string, + + OSVersion?: string, + + TargetName?: string, +} + diff --git a/pkg/js/generated/ts/redis.ts b/pkg/js/generated/ts/redis.ts new file mode 100755 index 0000000000..fbab318363 --- /dev/null +++ b/pkg/js/generated/ts/redis.ts @@ -0,0 +1,70 @@ + + +/** + * Connect tries to connect redis server with password + * @example + * ```javascript + * const redis = require('nuclei/redis'); + * const connected = redis.Connect('acme.com', 6379, 'password'); + * ``` + */ +export function Connect(host: string, port: number, password: string): boolean | null { + return null; +} + + + +/** + * GetServerInfo returns the server info for a redis server + * @example + * ```javascript + * const redis = require('nuclei/redis'); + * const info = redis.GetServerInfo('acme.com', 6379); + * ``` + */ +export function GetServerInfo(host: string, port: number): string | null { + return null; +} + + + +/** + * GetServerInfoAuth returns the server info for a redis server + * @example + * ```javascript + * const redis = require('nuclei/redis'); + * const info = redis.GetServerInfoAuth('acme.com', 6379, 'password'); + * ``` + */ +export function GetServerInfoAuth(host: string, port: number, password: string): string | null { + return null; +} + + + +/** + * IsAuthenticated checks if the redis server requires authentication + * @example + * ```javascript + * const redis = require('nuclei/redis'); + * const isAuthenticated = redis.IsAuthenticated('acme.com', 6379); + * ``` + */ +export function IsAuthenticated(host: string, port: number): boolean | null { + return null; +} + + + +/** + * RunLuaScript runs a lua script on the redis server + * @example + * ```javascript + * const redis = require('nuclei/redis'); + * const result = redis.RunLuaScript('acme.com', 6379, 'password', 'return redis.call("get", KEYS[1])'); + * ``` + */ +export function RunLuaScript(host: string, port: number, password: string, script: string): any | null { + return null; +} + diff --git a/pkg/js/generated/ts/rsync.ts b/pkg/js/generated/ts/rsync.ts new file mode 100755 index 0000000000..06ac1500a5 --- /dev/null +++ b/pkg/js/generated/ts/rsync.ts @@ -0,0 +1,50 @@ + + +/** + * RsyncClient is a minimal Rsync client for nuclei scripts. + * @example + * ```javascript + * const rsync = require('nuclei/rsync'); + * const client = new rsync.Client(); + * ``` + */ +export class RsyncClient { + + + // Constructor of RsyncClient + constructor() {} + /** + * IsRsync checks if a host is running a Rsync server. + * @example + * ```javascript + * const rsync = require('nuclei/rsync'); + * const isRsync = rsync.IsRsync('acme.com', 873); + * log(toJSON(isRsync)); + * ``` + */ + public IsRsync(host: string, port: number): IsRsyncResponse | null { + return null; + } + + +} + + + +/** + * IsRsyncResponse is the response from the IsRsync function. + * this is returned by IsRsync function. + * @example + * ```javascript + * const rsync = require('nuclei/rsync'); + * const isRsync = rsync.IsRsync('acme.com', 873); + * log(toJSON(isRsync)); + * ``` + */ +export interface IsRsyncResponse { + + IsRsync?: boolean, + + Banner?: string, +} + diff --git a/pkg/js/generated/ts/smb.ts b/pkg/js/generated/ts/smb.ts new file mode 100755 index 0000000000..8e577b3404 --- /dev/null +++ b/pkg/js/generated/ts/smb.ts @@ -0,0 +1,236 @@ + + +/** + * SMBClient is a client for SMB servers. + * Internally client uses github.com/zmap/zgrab2/lib/smb/smb driver. + * github.com/projectdiscovery/go-smb2 driver + * @example + * ```javascript + * const smb = require('nuclei/smb'); + * const client = new smb.Client(); + * ``` + */ +export class SMBClient { + + + // Constructor of SMBClient + constructor() {} + /** + * ConnectSMBInfoMode tries to connect to provided host and port + * and discovery SMB information + * Returns handshake log and error. If error is not nil, + * state will be false + * @example + * ```javascript + * const smb = require('nuclei/smb'); + * const client = new smb.Client(); + * const info = client.ConnectSMBInfoMode('acme.com', 445); + * log(to_json(info)); + * ``` + */ + public ConnectSMBInfoMode(host: string, port: number): SMBLog | null | null { + return null; + } + + + /** + * ListSMBv2Metadata tries to connect to provided host and port + * and list SMBv2 metadata. + * Returns metadata and error. If error is not nil, + * state will be false + * @example + * ```javascript + * const smb = require('nuclei/smb'); + * const client = new smb.Client(); + * const metadata = client.ListSMBv2Metadata('acme.com', 445); + * log(to_json(metadata)); + * ``` + */ + public ListSMBv2Metadata(host: string, port: number): ServiceSMB | null | null { + return null; + } + + + /** + * ListShares tries to connect to provided host and port + * and list shares by using given credentials. + * Credentials cannot be blank. guest or anonymous credentials + * can be used by providing empty password. + * @example + * ```javascript + * const smb = require('nuclei/smb'); + * const client = new smb.Client(); + * const shares = client.ListShares('acme.com', 445, 'username', 'password'); + * for (const share of shares) { + * log(share); + * } + * ``` + */ + public ListShares(host: string, port: number, user: string): string[] | null { + return null; + } + + + /** + * DetectSMBGhost tries to detect SMBGhost vulnerability + * by using SMBv3 compression feature. + * If the host is vulnerable, it returns true. + * @example + * ```javascript + * const smb = require('nuclei/smb'); + * const isSMBGhost = smb.DetectSMBGhost('acme.com', 445); + * ``` + */ + public DetectSMBGhost(host: string, port: number): boolean | null { + return null; + } + + +} + + + +/** + * HeaderLog Interface + */ +export interface HeaderLog { + + ProtocolID?: Uint8Array, + + Status?: number, + + Command?: number, + + Credits?: number, + + Flags?: number, +} + + + +/** + * NegotiationLog Interface + */ +export interface NegotiationLog { + + DialectRevision?: number, + + ServerGuid?: Uint8Array, + + Capabilities?: number, + + SystemTime?: number, + + ServerStartTime?: number, + + AuthenticationTypes?: string[], + + SecurityMode?: number, + + HeaderLog?: HeaderLog, +} + + + +/** + * SMBCapabilities Interface + */ +export interface SMBCapabilities { + + Leasing?: boolean, + + LargeMTU?: boolean, + + MultiChan?: boolean, + + Persist?: boolean, + + DirLeasing?: boolean, + + Encryption?: boolean, + + DFSSupport?: boolean, +} + + + +/** + * SMBLog Interface + */ +export interface SMBLog { + + NTLM?: string, + + GroupName?: string, + + HasNTLM?: boolean, + + SupportV1?: boolean, + + NativeOs?: string, + + Version?: SMBVersions, + + Capabilities?: SMBCapabilities, + + NegotiationLog?: NegotiationLog, + + SessionSetupLog?: SessionSetupLog, +} + + + +/** + * SMBVersions Interface + */ +export interface SMBVersions { + + Major?: number, + + Minor?: number, + + Revision?: number, + + VerString?: string, +} + + + +/** + * ServiceSMB Interface + */ +export interface ServiceSMB { + + DNSDomainName?: string, + + ForestName?: string, + + SigningEnabled?: boolean, + + SigningRequired?: boolean, + + OSVersion?: string, + + NetBIOSComputerName?: string, + + NetBIOSDomainName?: string, + + DNSComputerName?: string, +} + + + +/** + * SessionSetupLog Interface + */ +export interface SessionSetupLog { + + TargetName?: string, + + NegotiateFlags?: number, + + SetupFlags?: number, + + HeaderLog?: HeaderLog, +} + diff --git a/pkg/js/generated/ts/smtp.ts b/pkg/js/generated/ts/smtp.ts new file mode 100755 index 0000000000..e8dbd4e08f --- /dev/null +++ b/pkg/js/generated/ts/smtp.ts @@ -0,0 +1,191 @@ + + +/** + * SMTPClient is a minimal SMTP client for nuclei scripts. + * @example + * ```javascript + * const smtp = require('nuclei/smtp'); + * const client = new smtp.Client(); + * ``` + */ +export class SMTPClient { + + + // Constructor of SMTPClient + constructor() {} + /** + * IsSMTP checks if a host is running a SMTP server. + * @example + * ```javascript + * const smtp = require('nuclei/smtp'); + * const isSMTP = smtp.IsSMTP('acme.com', 25); + * log(toJSON(isSMTP)); + * ``` + */ + public IsSMTP(host: string, port: number): IsSMTPResponse | null { + return null; + } + + + /** + * IsOpenRelay checks if a host is an open relay. + * @example + * ```javascript + * const smtp = require('nuclei/smtp'); + * const message = new smtp.SMTPMessage(); + * message.From('xyz@projectdiscovery.io'); + * message.To('xyz2@projectdiscoveyr.io'); + * message.Subject('hello'); + * message.Body('hello'); + * const isRelay = smtp.IsOpenRelay('acme.com', 25, message); + * ``` + */ + public IsOpenRelay(host: string, port: number, msg: SMTPMessage): boolean | null { + return null; + } + + + /** + * SendMail sends an email using the SMTP protocol. + * @example + * ```javascript + * const smtp = require('nuclei/smtp'); + * const message = new smtp.SMTPMessage(); + * message.From('xyz@projectdiscovery.io'); + * message.To('xyz2@projectdiscoveyr.io'); + * message.Subject('hello'); + * message.Body('hello'); + * const isSent = smtp.SendMail('acme.com', 25, message); + * ``` + */ + public SendMail(host: string, port: string, msg: SMTPMessage): boolean | null { + return null; + } + + +} + + + +/** + * SMTPMessage is a message to be sent over SMTP + * @example + * ```javascript + * const smtp = require('nuclei/smtp'); + * const message = new smtp.SMTPMessage(); + * message.From('xyz@projectdiscovery.io'); + * ``` + */ +export class SMTPMessage { + + + // Constructor of SMTPMessage + constructor() {} + /** + * From adds the from field to the message + * @example + * ```javascript + * const smtp = require('nuclei/smtp'); + * const message = new smtp.SMTPMessage(); + * message.From('xyz@projectdiscovery.io'); + * ``` + */ + public From(email: string): SMTPMessage { + return this; + } + + + /** + * To adds the to field to the message + * @example + * ```javascript + * const smtp = require('nuclei/smtp'); + * const message = new smtp.SMTPMessage(); + * message.To('xyz@projectdiscovery.io'); + * ``` + */ + public To(email: string): SMTPMessage { + return this; + } + + + /** + * Subject adds the subject field to the message + * @example + * ```javascript + * const smtp = require('nuclei/smtp'); + * const message = new smtp.SMTPMessage(); + * message.Subject('hello'); + * ``` + */ + public Subject(sub: string): SMTPMessage { + return this; + } + + + /** + * Body adds the message body to the message + * @example + * ```javascript + * const smtp = require('nuclei/smtp'); + * const message = new smtp.SMTPMessage(); + * message.Body('hello'); + * ``` + */ + public Body(msg: Uint8Array): SMTPMessage { + return this; + } + + + /** + * Auth when called authenticates using username and password before sending the message + * @example + * ```javascript + * const smtp = require('nuclei/smtp'); + * const message = new smtp.SMTPMessage(); + * message.Auth('username', 'password'); + * ``` + */ + public Auth(username: string): SMTPMessage { + return this; + } + + + /** + * String returns the string representation of the message + * @example + * ```javascript + * const smtp = require('nuclei/smtp'); + * const message = new smtp.SMTPMessage(); + * message.From('xyz@projectdiscovery.io'); + * message.To('xyz2@projectdiscoveyr.io'); + * message.Subject('hello'); + * message.Body('hello'); + * log(message.String()); + * ``` + */ + public String(): string { + return ""; + } + + +} + + + +/** + * IsSMTPResponse is the response from the IsSMTP function. + * @example + * ```javascript + * const smtp = require('nuclei/smtp'); + * const isSMTP = smtp.IsSMTP('acme.com', 25); + * log(toJSON(isSMTP)); + * ``` + */ +export interface IsSMTPResponse { + + IsSMTP?: boolean, + + Banner?: string, +} + diff --git a/pkg/js/generated/ts/ssh.ts b/pkg/js/generated/ts/ssh.ts new file mode 100755 index 0000000000..6d10ce8376 --- /dev/null +++ b/pkg/js/generated/ts/ssh.ts @@ -0,0 +1,230 @@ + + +/** + * SSHClient is a client for SSH servers. + * Internally client uses github.com/zmap/zgrab2/lib/ssh driver. + * @example + * ```javascript + * const ssh = require('nuclei/ssh'); + * const client = new ssh.Client(); + * ``` + */ +export class SSHClient { + + + // Constructor of SSHClient + constructor() {} + /** + * SetTimeout sets the timeout for the SSH connection in seconds + * @example + * ```javascript + * const ssh = require('nuclei/ssh'); + * const client = new ssh.Client(); + * client.SetTimeout(10); + * ``` + */ + public SetTimeout(sec: number): void { + return; + } + + + /** + * Connect tries to connect to provided host and port + * with provided username and password with ssh. + * Returns state of connection and error. If error is not nil, + * state will be false + * @example + * ```javascript + * const ssh = require('nuclei/ssh'); + * const client = new ssh.Client(); + * const connected = client.Connect('acme.com', 22, 'username', 'password'); + * ``` + */ + public Connect(host: string, port: number, username: string): boolean | null { + return null; + } + + + /** + * ConnectWithKey tries to connect to provided host and port + * with provided username and private_key. + * Returns state of connection and error. If error is not nil, + * state will be false + * @example + * ```javascript + * const ssh = require('nuclei/ssh'); + * const client = new ssh.Client(); + * const privateKey = `-----BEGIN RSA PRIVATE KEY----- ...`; + * const connected = client.ConnectWithKey('acme.com', 22, 'username', privateKey); + * ``` + */ + public ConnectWithKey(host: string, port: number, username: string): boolean | null { + return null; + } + + + /** + * ConnectSSHInfoMode tries to connect to provided host and port + * with provided host and port + * Returns HandshakeLog and error. If error is not nil, + * state will be false + * HandshakeLog is a struct that contains information about the + * ssh connection + * @example + * ```javascript + * const ssh = require('nuclei/ssh'); + * const client = new ssh.Client(); + * const info = client.ConnectSSHInfoMode('acme.com', 22); + * log(to_json(info)); + * ``` + */ + public ConnectSSHInfoMode(host: string, port: number): HandshakeLog | null | null { + return null; + } + + + /** + * Run tries to open a new SSH session, then tries to execute + * the provided command in said session + * Returns string and error. If error is not nil, + * state will be false + * The string contains the command output + * @example + * ```javascript + * const ssh = require('nuclei/ssh'); + * const client = new ssh.Client(); + * client.Connect('acme.com', 22, 'username', 'password'); + * const output = client.Run('id'); + * log(output); + * ``` + */ + public Run(cmd: string): string | null { + return null; + } + + + /** + * Close closes the SSH connection and destroys the client + * Returns the success state and error. If error is not nil, + * state will be false + * @example + * ```javascript + * const ssh = require('nuclei/ssh'); + * const client = new ssh.Client(); + * client.Connect('acme.com', 22, 'username', 'password'); + * const closed = client.Close(); + * ``` + */ + public Close(): boolean | null { + return null; + } + + +} + + + +/** + * Algorithms Interface + */ +export interface Algorithms { + + Kex?: string, + + HostKey?: string, + + W?: DirectionAlgorithms, + + R?: DirectionAlgorithms, +} + + + +/** + * DirectionAlgorithms Interface + */ +export interface DirectionAlgorithms { + + Cipher?: string, + + MAC?: string, + + Compression?: string, +} + + + +/** + * EndpointId Interface + */ +export interface EndpointId { + + Raw?: string, + + ProtoVersion?: string, + + SoftwareVersion?: string, + + Comment?: string, +} + + + +/** + * HandshakeLog Interface + */ +export interface HandshakeLog { + + Banner?: string, + + UserAuth?: string[], + + AlgorithmSelection?: Algorithms, + + ServerID?: EndpointId, + + ClientID?: EndpointId, + + ServerKex?: KexInitMsg, + + ClientKex?: KexInitMsg, +} + + + +/** + * KexInitMsg Interface + */ +export interface KexInitMsg { + + CompressionClientServer?: string[], + + FirstKexFollows?: boolean, + + MACsClientServer?: string[], + + LanguagesClientServer?: string[], + + LanguagesServerClient?: string[], + + Reserved?: number, + + KexAlgos?: string[], + + CiphersClientServer?: string[], + + CiphersServerClient?: string[], + + MACsServerClient?: string[], + + CompressionServerClient?: string[], + + /** + * fixed size array of length: [16] + */ + + Cookie?: Uint8Array, + + ServerHostKeyAlgos?: string[], +} + diff --git a/pkg/js/generated/ts/structs.ts b/pkg/js/generated/ts/structs.ts new file mode 100755 index 0000000000..5c00f5ea86 --- /dev/null +++ b/pkg/js/generated/ts/structs.ts @@ -0,0 +1,49 @@ + + +/** + * StructsPack returns a byte slice containing the values of msg slice packed according to the given format. + * The items of msg slice must match the values required by the format exactly. + * Ex: structs.pack("H", 0) + * @example + * ```javascript + * const structs = require('nuclei/structs'); + * const packed = structs.Pack('H', [0]); + * ``` + */ +export function Pack(formatStr: string, msg: any): Uint8Array | null { + return null; +} + + + +/** + * StructsCalcSize returns the number of bytes needed to pack the values according to the given format. + * Ex: structs.CalcSize("H") + * @example + * ```javascript + * const structs = require('nuclei/structs'); + * const size = structs.CalcSize('H'); + * ``` + */ +export function StructsCalcSize(format: string): number | null { + return null; +} + + + +/** + * StructsUnpack the byte slice (presumably packed by Pack(format, msg)) according to the given format. + * The result is a []interface{} slice even if it contains exactly one item. + * The byte slice must contain not less the amount of data required by the format + * (len(msg) must more or equal CalcSize(format)). + * Ex: structs.Unpack(">I", buff[:nb]) + * @example + * ```javascript + * const structs = require('nuclei/structs'); + * const result = structs.Unpack('H', [0]); + * ``` + */ +export function Unpack(format: string, msg: Uint8Array): any | null { + return null; +} + diff --git a/pkg/js/generated/ts/telnet.ts b/pkg/js/generated/ts/telnet.ts new file mode 100755 index 0000000000..5ddabc4712 --- /dev/null +++ b/pkg/js/generated/ts/telnet.ts @@ -0,0 +1,50 @@ + + +/** + * TelnetClient is a minimal Telnet client for nuclei scripts. + * @example + * ```javascript + * const telnet = require('nuclei/telnet'); + * const client = new telnet.Client(); + * ``` + */ +export class TelnetClient { + + + // Constructor of TelnetClient + constructor() {} + /** + * IsTelnet checks if a host is running a Telnet server. + * @example + * ```javascript + * const telnet = require('nuclei/telnet'); + * const isTelnet = telnet.IsTelnet('acme.com', 23); + * log(toJSON(isTelnet)); + * ``` + */ + public IsTelnet(host: string, port: number): IsTelnetResponse | null { + return null; + } + + +} + + + +/** + * IsTelnetResponse is the response from the IsTelnet function. + * this is returned by IsTelnet function. + * @example + * ```javascript + * const telnet = require('nuclei/telnet'); + * const isTelnet = telnet.IsTelnet('acme.com', 23); + * log(toJSON(isTelnet)); + * ``` + */ +export interface IsTelnetResponse { + + IsTelnet?: boolean, + + Banner?: string, +} + diff --git a/pkg/js/generated/ts/vnc.ts b/pkg/js/generated/ts/vnc.ts new file mode 100755 index 0000000000..86a0bcd021 --- /dev/null +++ b/pkg/js/generated/ts/vnc.ts @@ -0,0 +1,51 @@ + + +/** + * VNCClient is a minimal VNC client for nuclei scripts. + * @example + * ```javascript + * const vnc = require('nuclei/vnc'); + * const client = new vnc.Client(); + * ``` + */ +export class VNCClient { + + + // Constructor of VNCClient + constructor() {} + /** + * IsVNC checks if a host is running a VNC server. + * It returns a boolean indicating if the host is running a VNC server + * and the banner of the VNC server. + * @example + * ```javascript + * const vnc = require('nuclei/vnc'); + * const isVNC = vnc.IsVNC('acme.com', 5900); + * log(toJSON(isVNC)); + * ``` + */ + public IsVNC(host: string, port: number): IsVNCResponse | null { + return null; + } + + +} + + + +/** + * IsVNCResponse is the response from the IsVNC function. + * @example + * ```javascript + * const vnc = require('nuclei/vnc'); + * const isVNC = vnc.IsVNC('acme.com', 5900); + * log(toJSON(isVNC)); + * ``` + */ +export interface IsVNCResponse { + + IsVNC?: boolean, + + Banner?: string, +} + diff --git a/pkg/js/gojs/gojs.go b/pkg/js/gojs/gojs.go index 0b47cbd1de..3b43fe13fb 100644 --- a/pkg/js/gojs/gojs.go +++ b/pkg/js/gojs/gojs.go @@ -5,6 +5,7 @@ import ( "github.com/dop251/goja" "github.com/dop251/goja_nodejs/require" + "github.com/projectdiscovery/nuclei/v3/pkg/js/utils" ) type Objects map[string]interface{} @@ -75,3 +76,10 @@ func (p *GojaModule) Register() Module { return p } + +// GetClassConstructor returns a constructor for any given go struct type for goja runtime +func GetClassConstructor[T any](instance *T) func(call goja.ConstructorCall, runtime *goja.Runtime) *goja.Object { + return func(call goja.ConstructorCall, runtime *goja.Runtime) *goja.Object { + return utils.LinkConstructor[*T](call, runtime, instance) + } +} diff --git a/pkg/js/libs/bytes/buffer.go b/pkg/js/libs/bytes/buffer.go index 3a3058bf84..e384741826 100644 --- a/pkg/js/libs/bytes/buffer.go +++ b/pkg/js/libs/bytes/buffer.go @@ -5,71 +5,132 @@ import ( "github.com/dop251/goja" "github.com/projectdiscovery/nuclei/v3/pkg/js/libs/structs" + "github.com/projectdiscovery/nuclei/v3/pkg/js/utils" ) -// Buffer is a minimal buffer implementation over a byte slice -// that is used to pack/unpack binary data in nuclei js integration. -type Buffer struct { - buf []byte -} +type ( + // Buffer is a bytes/Uint8Array type in javascript + // @example + // ```javascript + // const bytes = require('nuclei/bytes'); + // const bytes = new bytes.Buffer(); + // ``` + // @example + // ```javascript + // const bytes = require('nuclei/bytes'); + // // optionally it can accept existing byte/Uint8Array as input + // const bytes = new bytes.Buffer([1, 2, 3]); + // ``` + Buffer struct { + buf []byte + } +) // NewBuffer creates a new buffer from a byte slice. -func NewBuffer(call goja.ConstructorCall) interface{} { - obj := &Buffer{} - - obj.buf = make([]byte, 0) - return map[string]interface{}{ - "Write": obj.Write, - "WriteString": obj.WriteString, - "Pack": obj.Pack, - "Bytes": obj.Bytes, - "String": obj.String, - "Len": obj.Len, - "Hex": obj.Hex, - "Hexdump": obj.Hexdump, +func NewBuffer(call goja.ConstructorCall, runtime *goja.Runtime) *goja.Object { + if len(call.Arguments) > 0 { + if arg, ok := call.Argument(0).Export().([]byte); ok { + return utils.LinkConstructor(call, runtime, &Buffer{buf: arg}) + } else { + utils.NewNucleiJS(runtime).Throw("Invalid argument type. Expected bytes/Uint8Array as input but got %T", call.Argument(0).Export()) + } } + return utils.LinkConstructor(call, runtime, &Buffer{}) } -// Write appends a byte slice to the buffer. +// Write appends the given data to the buffer. +// @example +// ```javascript +// const bytes = require('nuclei/bytes'); +// const buffer = new bytes.Buffer(); +// buffer.Write([1, 2, 3]); +// ``` func (b *Buffer) Write(data []byte) *Buffer { b.buf = append(b.buf, data...) return b } -// WriteString appends a string to the buffer. +// WriteString appends the given string data to the buffer. +// @example +// ```javascript +// const bytes = require('nuclei/bytes'); +// const buffer = new bytes.Buffer(); +// buffer.WriteString('hello'); +// ``` func (b *Buffer) WriteString(data string) *Buffer { b.buf = append(b.buf, []byte(data)...) return b } -// Bytes returns the byte slice of the buffer. +// Bytes returns the byte representation of the buffer. +// @example +// ```javascript +// const bytes = require('nuclei/bytes'); +// const buffer = new bytes.Buffer(); +// buffer.WriteString('hello'); +// log(buffer.Bytes()); +// ``` func (b *Buffer) Bytes() []byte { return b.buf } // String returns the string representation of the buffer. +// @example +// ```javascript +// const bytes = require('nuclei/bytes'); +// const buffer = new bytes.Buffer(); +// buffer.WriteString('hello'); +// log(buffer.String()); +// ``` func (b *Buffer) String() string { return string(b.buf) } // Len returns the length of the buffer. +// @example +// ```javascript +// const bytes = require('nuclei/bytes'); +// const buffer = new bytes.Buffer(); +// buffer.WriteString('hello'); +// log(buffer.Len()); +// ``` func (b *Buffer) Len() int { return len(b.buf) } // Hex returns the hex representation of the buffer. +// @example +// ```javascript +// const bytes = require('nuclei/bytes'); +// const buffer = new bytes.Buffer(); +// buffer.WriteString('hello'); +// log(buffer.Hex()); +// ``` func (b *Buffer) Hex() string { return hex.EncodeToString(b.buf) } // Hexdump returns the hexdump representation of the buffer. +// @example +// ```javascript +// const bytes = require('nuclei/bytes'); +// const buffer = new bytes.Buffer(); +// buffer.WriteString('hello'); +// log(buffer.Hexdump()); +// ``` func (b *Buffer) Hexdump() string { return hex.Dump(b.buf) } // Pack uses structs.Pack and packs given data and appends it to the buffer. // it packs the data according to the given format. -func (b *Buffer) Pack(formatStr string, msg []interface{}) error { +// @example +// ```javascript +// const bytes = require('nuclei/bytes'); +// const buffer = new bytes.Buffer(); +// buffer.Pack('I', 123); +// ``` +func (b *Buffer) Pack(formatStr string, msg any) error { bin, err := structs.Pack(formatStr, msg) if err != nil { return err diff --git a/pkg/js/libs/fs/fs.go b/pkg/js/libs/fs/fs.go index 5dcbb03812..e3a3fd7bdd 100644 --- a/pkg/js/libs/fs/fs.go +++ b/pkg/js/libs/fs/fs.go @@ -6,9 +6,27 @@ import ( "github.com/projectdiscovery/nuclei/v3/pkg/protocols/common/protocolstate" ) -// ListDir lists all files and directories within a path +// ListDir lists itemType values within a directory // depending on the itemType provided -// itemType can be any one of ['file','dir','all'] +// itemType can be any one of ['file','dir',”] +// @example +// ```javascript +// const fs = require('nuclei/fs'); +// // this will only return files in /tmp directory +// const files = fs.ListDir('/tmp', 'file'); +// ``` +// @example +// ```javascript +// const fs = require('nuclei/fs'); +// // this will only return directories in /tmp directory +// const dirs = fs.ListDir('/tmp', 'dir'); +// ``` +// @example +// ```javascript +// const fs = require('nuclei/fs'); +// // when no itemType is provided, it will return both files and directories +// const items = fs.ListDir('/tmp'); +// ``` func ListDir(path string, itemType string) ([]string, error) { finalPath, err := protocolstate.NormalizePath(path) if err != nil { @@ -32,6 +50,13 @@ func ListDir(path string, itemType string) ([]string, error) { } // ReadFile reads file contents within permitted paths +// and returns content as byte array +// @example +// ```javascript +// const fs = require('nuclei/fs'); +// // here permitted directories are $HOME/nuclei-templates/* +// const content = fs.ReadFile('helpers/usernames.txt'); +// ``` func ReadFile(path string) ([]byte, error) { finalPath, err := protocolstate.NormalizePath(path) if err != nil { @@ -43,6 +68,12 @@ func ReadFile(path string) ([]byte, error) { // ReadFileAsString reads file contents within permitted paths // and returns content as string +// @example +// ```javascript +// const fs = require('nuclei/fs'); +// // here permitted directories are $HOME/nuclei-templates/* +// const content = fs.ReadFileAsString('helpers/usernames.txt'); +// ``` func ReadFileAsString(path string) (string, error) { bin, err := ReadFile(path) if err != nil { @@ -52,7 +83,14 @@ func ReadFileAsString(path string) (string, error) { } // ReadFilesFromDir reads all files from a directory -// and returns a array with file contents of all files +// and returns a string array with file contents of all files +// @example +// ```javascript +// const fs = require('nuclei/fs'); +// // here permitted directories are $HOME/nuclei-templates/* +// const contents = fs.ReadFilesFromDir('helpers/ssh-keys'); +// log(contents); +// ``` func ReadFilesFromDir(dir string) ([]string, error) { files, err := ListDir(dir, "file") if err != nil { diff --git a/pkg/js/libs/ikev2/ikev2.go b/pkg/js/libs/ikev2/ikev2.go index c41fedf2f7..37e013c91a 100644 --- a/pkg/js/libs/ikev2/ikev2.go +++ b/pkg/js/libs/ikev2/ikev2.go @@ -1,6 +1,7 @@ package ikev2 import ( + "fmt" "io" "github.com/projectdiscovery/n3iwf/pkg/ike/message" @@ -11,31 +12,91 @@ func init() { logger.Log.SetOutput(io.Discard) } -// IKEMessage is the IKEv2 message -// -// IKEv2 implements a limited subset of IKEv2 Protocol, specifically -// the IKE_NOTIFY and IKE_NONCE payloads and the IKE_SA_INIT exchange. -type IKEMessage struct { - InitiatorSPI uint64 - Version uint8 - ExchangeType uint8 - Flags uint8 - Payloads []IKEPayload +type ( + // IKEMessage is the IKEv2 message + // + // IKEv2 implements a limited subset of IKEv2 Protocol, specifically + // the IKE_NOTIFY and IKE_NONCE payloads and the IKE_SA_INIT exchange. + IKEMessage struct { + InitiatorSPI uint64 + Version uint8 + ExchangeType uint8 + Flags uint8 + payloads []IKEPayload + } +) + +// AppendPayload appends a payload to the IKE message +// payload can be any of the payloads like IKENotification, IKENonce, etc. +// @example +// ```javascript +// const ikev2 = require('nuclei/ikev2'); +// const message = new ikev2.IKEMessage(); +// const nonce = new ikev2.IKENonce(); +// nonce.NonceData = [1, 2, 3]; +// message.AppendPayload(nonce); +// ``` +func (m *IKEMessage) AppendPayload(payload any) error { + if _, ok := payload.(IKEPayload); !ok { + return fmt.Errorf("invalid payload type only types defined in ikev module like IKENotification, IKENonce, etc. are allowed") + } + m.payloads = append(m.payloads, payload.(IKEPayload)) + return nil +} + +// Encode encodes the final IKE message +// @example +// ```javascript +// const ikev2 = require('nuclei/ikev2'); +// const message = new ikev2.IKEMessage(); +// const nonce = new ikev2.IKENonce(); +// nonce.NonceData = [1, 2, 3]; +// message.AppendPayload(nonce); +// log(message.Encode()); +// ``` +func (m *IKEMessage) Encode() ([]byte, error) { + var payloads message.IKEPayloadContainer + for _, payload := range m.payloads { + p, err := payload.encode() + if err != nil { + return nil, err + } + payloads = append(payloads, p) + } + + msg := &message.IKEMessage{ + InitiatorSPI: m.InitiatorSPI, + Version: m.Version, + ExchangeType: m.ExchangeType, + Flags: m.Flags, + Payloads: payloads, + } + encoded, err := msg.Encode() + return encoded, err } // IKEPayload is the IKEv2 payload interface -// // All the payloads like IKENotification, IKENonce, etc. implement // this interface. type IKEPayload interface { encode() (message.IKEPayload, error) } -// IKEv2Notify is the IKEv2 Notification payload -type IKENotification struct { - NotifyMessageType uint16 - NotificationData []byte -} +type ( + // IKEv2Notify is the IKEv2 Notification payload + // this implements the IKEPayload interface + // @example + // ```javascript + // const ikev2 = require('nuclei/ikev2'); + // const notify = new ikev2.IKENotification(); + // notify.NotifyMessageType = ikev2.IKE_NOTIFY_NO_PROPOSAL_CHOSEN; + // notify.NotificationData = [1, 2, 3]; + // ``` + IKENotification struct { + NotifyMessageType uint16 + NotificationData []byte + } +) // encode encodes the IKEv2 Notification payload func (i *IKENotification) encode() (message.IKEPayload, error) { @@ -63,10 +124,19 @@ const ( IKE_FLAGS_InitiatorBitCheck = 0x08 ) -// IKENonce is the IKEv2 Nonce payload -type IKENonce struct { - NonceData []byte -} +type ( + // IKENonce is the IKEv2 Nonce payload + // this implements the IKEPayload interface + // @example + // ```javascript + // const ikev2 = require('nuclei/ikev2'); + // const nonce = new ikev2.IKENonce(); + // nonce.NonceData = [1, 2, 3]; + // ``` + IKENonce struct { + NonceData []byte + } +) // encode encodes the IKEv2 Nonce payload func (i *IKENonce) encode() (message.IKEPayload, error) { @@ -75,30 +145,3 @@ func (i *IKENonce) encode() (message.IKEPayload, error) { } return &nonce, nil } - -// AppendPayload appends a payload to the IKE message -func (m *IKEMessage) AppendPayload(payload IKEPayload) { - m.Payloads = append(m.Payloads, payload) -} - -// Encode encodes the final IKE message -func (m *IKEMessage) Encode() ([]byte, error) { - var payloads message.IKEPayloadContainer - for _, payload := range m.Payloads { - p, err := payload.encode() - if err != nil { - return nil, err - } - payloads = append(payloads, p) - } - - msg := &message.IKEMessage{ - InitiatorSPI: m.InitiatorSPI, - Version: m.Version, - ExchangeType: m.ExchangeType, - Flags: m.Flags, - Payloads: payloads, - } - encoded, err := msg.Encode() - return encoded, err -} diff --git a/pkg/js/libs/kerberos/kerberosx.go b/pkg/js/libs/kerberos/kerberosx.go index 7d2be507f2..bb00fe2995 100644 --- a/pkg/js/libs/kerberos/kerberosx.go +++ b/pkg/js/libs/kerberos/kerberosx.go @@ -13,35 +13,51 @@ import ( ConversionUtil "github.com/projectdiscovery/utils/conversion" ) -// Known Issues: -// Hardcoded timeout in gokrb5 library -// TGT / Session Handling not exposed - -// EnumerateUserResponse is the response from EnumerateUser -type EnumerateUserResponse struct { - Valid bool `json:"valid"` - ASREPHash string `json:"asrep_hash"` - Error string `json:"error"` -} +type ( + // EnumerateUserResponse is the response from EnumerateUser + EnumerateUserResponse struct { + Valid bool `json:"valid"` + ASREPHash string `json:"asrep_hash"` + Error string `json:"error"` + } +) -// TGS is the response from GetServiceTicket -type TGS struct { - Ticket messages.Ticket `json:"ticket"` - Hash string `json:"hash"` - ErrMsg string `json:"error"` -} +type ( + // TGS is the response from GetServiceTicket + TGS struct { + Ticket messages.Ticket `json:"ticket"` + Hash string `json:"hash"` + ErrMsg string `json:"error"` + } +) -// Config is extra configuration for the kerberos client -type Config struct { - ip string - timeout int // in seconds -} +type ( + // Config is extra configuration for the kerberos client + Config struct { + ip string + timeout int // in seconds + } +) +// SetIPAddress sets the IP address for the kerberos client +// @example +// ```javascript +// const kerberos = require('nuclei/kerberos'); +// const cfg = new kerberos.Config(); +// cfg.SetIPAddress('10.10.10.1'); +// ``` func (c *Config) SetIPAddress(ip string) *Config { c.ip = ip return c } +// SetTimeout sets the RW timeout for the kerberos client +// @example +// ```javascript +// const kerberos = require('nuclei/kerberos'); +// const cfg = new kerberos.Config(); +// cfg.SetTimeout(5); +// ``` func (c *Config) SetTimeout(timeout int) *Config { c.timeout = timeout return c @@ -53,19 +69,27 @@ func (c *Config) SetTimeout(timeout int) *Config { // DomainController: dc.acme.com (Domain Controller / Active Directory Server) // KDC: kdc.acme.com (Key Distribution Center / Authentication Server) -// Client is kerberos client -type Client struct { - nj *utils.NucleiJS // helper functions/bindings - Krb5Config *kconfig.Config - Realm string - config Config -} +type ( + // Known Issues: + // Hardcoded timeout in gokrb5 library + // TGT / Session Handling not exposed + // Client is kerberos client + // @example + // ```javascript + // const kerberos = require('nuclei/kerberos'); + // // if controller is empty a dns lookup for default kdc server will be performed + // const client = new kerberos.Client('acme.com', 'kdc.acme.com'); + // ``` + Client struct { + nj *utils.NucleiJS // helper functions/bindings + Krb5Config *kconfig.Config + Realm string + config Config + } +) // Constructor for KerberosClient -// if controller is empty a dns lookup for default kdc server will be performed -// Signature: Client(domain, {controller}) -// @param domain: string -// @param controller: string (optional) +// Constructor: constructor(public domain: string, public controller?: string) // When controller is empty or not given krb5 will perform a DNS lookup for the default KDC server // and retrieve its address from the DNS server func NewKerberosClient(call goja.ConstructorCall, runtime *goja.Runtime) *goja.Object { @@ -119,11 +143,15 @@ func NewKerberosClient(call goja.ConstructorCall, runtime *goja.Runtime) *goja.O // NewKerberosClientFromString creates a new kerberos client from a string // by parsing krb5.conf -// @param cfg: string -// Example krb5.conf: +// @example +// ```javascript +// const kerberos = require('nuclei/kerberos'); +// const client = kerberos.NewKerberosClientFromString(` // [libdefaults] // default_realm = ACME.COM // dns_lookup_kdc = true +// `); +// ``` func NewKerberosClientFromString(cfg string) (*Client, error) { config, err := kconfig.NewFromString(cfg) if err != nil { @@ -133,10 +161,17 @@ func NewKerberosClientFromString(cfg string) (*Client, error) { } // SetConfig sets additional config for the kerberos client -// Signature: SetConfig(cfg) -// @param cfg: @Config // Note: as of now ip and timeout overrides are only supported // in EnumerateUser due to fastdialer but can be extended to other methods currently +// @example +// ```javascript +// const kerberos = require('nuclei/kerberos'); +// const client = new kerberos.Client('acme.com', 'kdc.acme.com'); +// const cfg = new kerberos.Config(); +// cfg.SetIPAddress('192.168.100.22'); +// cfg.SetTimeout(5); +// client.SetConfig(cfg); +// ``` func (c *Client) SetConfig(cfg *Config) { if cfg == nil { c.nj.Throw("config cannot be nil") @@ -145,8 +180,13 @@ func (c *Client) SetConfig(cfg *Config) { } // EnumerateUser and attempt to get AS-REP hash by disabling PA-FX-FAST -// Signature: EnumerateUser(username, {password}) -// @param username: string +// @example +// ```javascript +// const kerberos = require('nuclei/kerberos'); +// const client = new kerberos.Client('acme.com', 'kdc.acme.com'); +// const resp = client.EnumerateUser('pdtm'); +// log(resp); +// ``` func (c *Client) EnumerateUser(username string) (EnumerateUserResponse, error) { c.nj.Require(c.Krb5Config != nil, "Kerberos client not initialized") password := "password" @@ -192,11 +232,14 @@ func (c *Client) EnumerateUser(username string) (EnumerateUserResponse, error) { return resp, nil } -// GetServiceTicket returns a TGS for a given user, password, target and SPN -// Signature: GetServiceTicket(User, Pass, Target, SPN) -// @param User: string -// @param Pass: string -// @param SPN: string Service Principal Name +// GetServiceTicket returns a TGS for a given user, password and SPN +// @example +// ```javascript +// const kerberos = require('nuclei/kerberos'); +// const client = new kerberos.Client('acme.com', 'kdc.acme.com'); +// const resp = client.GetServiceTicket('pdtm', 'password', 'HOST/CLIENT1'); +// log(resp); +// ``` func (c *Client) GetServiceTicket(User, Pass, SPN string) (TGS, error) { c.nj.Require(c.Krb5Config != nil, "Kerberos client not initialized") c.nj.Require(User != "", "User cannot be empty") diff --git a/pkg/js/libs/kerberos/sendtokdc.go b/pkg/js/libs/kerberos/sendtokdc.go index e1bc27026a..7e14386a7d 100644 --- a/pkg/js/libs/kerberos/sendtokdc.go +++ b/pkg/js/libs/kerberos/sendtokdc.go @@ -20,6 +20,13 @@ import ( // sendtokdc.go deals with actual sending and receiving responses from KDC // SendToKDC sends a message to the KDC and returns the response. +// It first tries to send the message over TCP, and if that fails, it falls back to UDP.(and vice versa) +// @example +// ```javascript +// const kerberos = require('nuclei/kerberos'); +// const client = new kerberos.Client('acme.com'); +// const response = kerberos.SendToKDC(client, 'message'); +// ``` func SendToKDC(kclient *Client, msg string) (string, error) { if kclient == nil || kclient.nj == nil || kclient.Krb5Config == nil || kclient.Realm == "" { return "", fmt.Errorf("kerberos client is not initialized") diff --git a/pkg/js/libs/ldap/adenum.go b/pkg/js/libs/ldap/adenum.go index 9222a132d5..0939ec826c 100644 --- a/pkg/js/libs/ldap/adenum.go +++ b/pkg/js/libs/ldap/adenum.go @@ -17,11 +17,11 @@ import ( // // https://learn.microsoft.com/en-us/troubleshoot/windows-server/identity/useraccountcontrol-manipulate-account-properties const ( - FilterIsPerson = "(objectCategory=person)" - FilterIsGroup = "(objectCategory=group)" - FilterIsComputer = "(objectCategory=computer)" - FilterIsAdmin = "(adminCount=1)" - FilterHasServicePrincipalName = "(servicePrincipalName=*)" + FilterIsPerson = "(objectCategory=person)" // The object is a person. + FilterIsGroup = "(objectCategory=group)" // The object is a group. + FilterIsComputer = "(objectCategory=computer)" // The object is a computer. + FilterIsAdmin = "(adminCount=1)" // The object is an admin. + FilterHasServicePrincipalName = "(servicePrincipalName=*)" // The object has a service principal name. FilterLogonScript = "(userAccountControl:1.2.840.113556.1.4.803:=1)" // The logon script will be run. FilterAccountDisabled = "(userAccountControl:1.2.840.113556.1.4.803:=2)" // The user account is disabled. FilterAccountEnabled = "(!(userAccountControl:1.2.840.113556.1.4.803:=2))" // The user account is enabled. @@ -49,6 +49,11 @@ const ( ) // JoinFilters joins multiple filters into a single filter +// @example +// ```javascript +// const ldap = require('nuclei/ldap'); +// const filter = ldap.JoinFilters(ldap.FilterIsPerson, ldap.FilterAccountEnabled); +// ``` func JoinFilters(filters ...string) string { var builder strings.Builder builder.WriteString("(&") @@ -60,24 +65,42 @@ func JoinFilters(filters ...string) string { } // NegativeFilter returns a negative filter for a given filter +// @example +// ```javascript +// const ldap = require('nuclei/ldap'); +// const filter = ldap.NegativeFilter(ldap.FilterIsPerson); +// ``` func NegativeFilter(filter string) string { return fmt.Sprintf("(!%s)", filter) } -// ADObject represents an Active Directory object -type ADObject struct { - DistinguishedName string - SAMAccountName string - PWDLastSet string - LastLogon string - MemberOf []string - ServicePrincipalName []string -} +type ( + // ADObject represents an Active Directory object + // @example + // ```javascript + // const ldap = require('nuclei/ldap'); + // const client = new ldap.Client('ldap://ldap.example.com', 'acme.com'); + // const users = client.GetADUsers(); + // log(to_json(users)); + ADObject struct { + DistinguishedName string + SAMAccountName string + PWDLastSet string + LastLogon string + MemberOf []string + ServicePrincipalName []string + } +) // FindADObjects finds AD objects based on a filter // and returns them as a list of ADObject -// @param filter: string -// @return []ADObject +// @example +// ```javascript +// const ldap = require('nuclei/ldap'); +// const client = new ldap.Client('ldap://ldap.example.com', 'acme.com'); +// const users = client.FindADObjects(ldap.FilterIsPerson); +// log(to_json(users)); +// ``` func (c *Client) FindADObjects(filter string) []ADObject { c.nj.Require(c.conn != nil, "no existing connection") sr := ldap.NewSearchRequest( @@ -114,69 +137,129 @@ func (c *Client) FindADObjects(filter string) []ADObject { // GetADUsers returns all AD users // using FilterIsPerson filter query -// @return []ADObject +// @example +// ```javascript +// const ldap = require('nuclei/ldap'); +// const client = new ldap.Client('ldap://ldap.example.com', 'acme.com'); +// const users = client.GetADUsers(); +// log(to_json(users)); +// ``` func (c *Client) GetADUsers() []ADObject { return c.FindADObjects(FilterIsPerson) } // GetADActiveUsers returns all AD users // using FilterIsPerson and FilterAccountEnabled filter query -// @return []ADObject +// @example +// ```javascript +// const ldap = require('nuclei/ldap'); +// const client = new ldap.Client('ldap://ldap.example.com', 'acme.com'); +// const users = client.GetADActiveUsers(); +// log(to_json(users)); +// ``` func (c *Client) GetADActiveUsers() []ADObject { return c.FindADObjects(JoinFilters(FilterIsPerson, FilterAccountEnabled)) } // GetAdUserWithNeverExpiringPasswords returns all AD users // using FilterIsPerson and FilterDontExpirePassword filter query -// @return []ADObject +// @example +// ```javascript +// const ldap = require('nuclei/ldap'); +// const client = new ldap.Client('ldap://ldap.example.com', 'acme.com'); +// const users = client.GetADUserWithNeverExpiringPasswords(); +// log(to_json(users)); +// ``` func (c *Client) GetADUserWithNeverExpiringPasswords() []ADObject { return c.FindADObjects(JoinFilters(FilterIsPerson, FilterDontExpirePassword)) } // GetADUserTrustedForDelegation returns all AD users that are trusted for delegation // using FilterIsPerson and FilterTrustedForDelegation filter query -// @return []ADObject +// @example +// ```javascript +// const ldap = require('nuclei/ldap'); +// const client = new ldap.Client('ldap://ldap.example.com', 'acme.com'); +// const users = client.GetADUserTrustedForDelegation(); +// log(to_json(users)); +// ``` func (c *Client) GetADUserTrustedForDelegation() []ADObject { return c.FindADObjects(JoinFilters(FilterIsPerson, FilterTrustedForDelegation)) } // GetADUserWithPasswordNotRequired returns all AD users that do not require a password // using FilterIsPerson and FilterPasswordNotRequired filter query -// @return []ADObject +// @example +// ```javascript +// const ldap = require('nuclei/ldap'); +// const client = new ldap.Client('ldap://ldap.example.com', 'acme.com'); +// const users = client.GetADUserWithPasswordNotRequired(); +// log(to_json(users)); +// ``` func (c *Client) GetADUserWithPasswordNotRequired() []ADObject { return c.FindADObjects(JoinFilters(FilterIsPerson, FilterPasswordNotRequired)) } // GetADGroups returns all AD groups // using FilterIsGroup filter query -// @return []ADObject +// @example +// ```javascript +// const ldap = require('nuclei/ldap'); +// const client = new ldap.Client('ldap://ldap.example.com', 'acme.com'); +// const groups = client.GetADGroups(); +// log(to_json(groups)); +// ``` func (c *Client) GetADGroups() []ADObject { return c.FindADObjects(FilterIsGroup) } // GetADDCList returns all AD domain controllers // using FilterIsComputer, FilterAccountEnabled and FilterServerTrustAccount filter query -// @return []ADObject +// @example +// ```javascript +// const ldap = require('nuclei/ldap'); +// const client = new ldap.Client('ldap://ldap.example.com', 'acme.com'); +// const dcs = client.GetADDCList(); +// log(to_json(dcs)); +// ``` func (c *Client) GetADDCList() []ADObject { return c.FindADObjects(JoinFilters(FilterIsComputer, FilterAccountEnabled, FilterServerTrustAccount)) } // GetADAdmins returns all AD admins // using FilterIsPerson, FilterAccountEnabled and FilterIsAdmin filter query -// @return []ADObject +// @example +// ```javascript +// const ldap = require('nuclei/ldap'); +// const client = new ldap.Client('ldap://ldap.example.com', 'acme.com'); +// const admins = client.GetADAdmins(); +// log(to_json(admins)); +// ``` func (c *Client) GetADAdmins() []ADObject { return c.FindADObjects(JoinFilters(FilterIsPerson, FilterAccountEnabled, FilterIsAdmin)) } // GetADUserKerberoastable returns all AD users that are kerberoastable // using FilterIsPerson, FilterAccountEnabled and FilterHasServicePrincipalName filter query -// @return []ADObject +// @example +// ```javascript +// const ldap = require('nuclei/ldap'); +// const client = new ldap.Client('ldap://ldap.example.com', 'acme.com'); +// const kerberoastable = client.GetADUserKerberoastable(); +// log(to_json(kerberoastable)); +// ``` func (c *Client) GetADUserKerberoastable() []ADObject { return c.FindADObjects(JoinFilters(FilterIsPerson, FilterAccountEnabled, FilterHasServicePrincipalName)) } // GetADDomainSID returns the SID of the AD domain -// @return string +// @example +// ```javascript +// const ldap = require('nuclei/ldap'); +// const client = new ldap.Client('ldap://ldap.example.com', 'acme.com'); +// const domainSID = client.GetADDomainSID(); +// log(domainSID); +// ``` func (c *Client) GetADDomainSID() string { r := c.Search(FilterServerTrustAccount, "objectSid") c.nj.Require(len(r) > 0, "no result from GetADDomainSID query") diff --git a/pkg/js/libs/ldap/ldap.go b/pkg/js/libs/ldap/ldap.go index 3381859009..5f03611cb2 100644 --- a/pkg/js/libs/ldap/ldap.go +++ b/pkg/js/libs/ldap/ldap.go @@ -14,37 +14,59 @@ import ( "github.com/projectdiscovery/nuclei/v3/pkg/protocols/common/protocolstate" ) -// Client is a client for ldap protocol in nuclei -type Client struct { - Host string // Hostname - Port int // Port - Realm string // Realm - BaseDN string // BaseDN (generated from Realm) +type ( + // Client is a client for ldap protocol in nuclei + // @example + // ```javascript + // const ldap = require('nuclei/ldap'); + // // here ldap.example.com is the ldap server and acme.com is the realm + // const client = new ldap.Client('ldap://ldap.example.com', 'acme.com'); + // ``` + // @example + // ```javascript + // const ldap = require('nuclei/ldap'); + // const cfg = new ldap.Config(); + // cfg.Timeout = 10; + // cfg.ServerName = 'ldap.internal.acme.com'; + // // optional config can be passed as third argument + // const client = new ldap.Client('ldap://ldap.example.com', 'acme.com', cfg); + // ``` + Client struct { + Host string // Hostname + Port int // Port + Realm string // Realm + BaseDN string // BaseDN (generated from Realm) - // unexported - nj *utils.NucleiJS // nuclei js utils - conn *ldap.Conn - cfg Config -} + // unexported + nj *utils.NucleiJS // nuclei js utils + conn *ldap.Conn + cfg Config + } +) -// Config is extra configuration for the ldap client -type Config struct { - // Timeout is the timeout for the ldap client in seconds - Timeout int - ServerName string // default to host (when using tls) - Upgrade bool // when true first connects to non-tls and then upgrades to tls -} +type ( + // Config is extra configuration for the ldap client + // @example + // ```javascript + // const ldap = require('nuclei/ldap'); + // const cfg = new ldap.Config(); + // cfg.Timeout = 10; + // cfg.ServerName = 'ldap.internal.acme.com'; + // cfg.Upgrade = true; // upgrade to tls + // ``` + Config struct { + // Timeout is the timeout for the ldap client in seconds + Timeout int + ServerName string // default to host (when using tls) + Upgrade bool // when true first connects to non-tls and then upgrades to tls + } +) // Constructor for creating a new ldap client // The following schemas are supported for url: ldap://, ldaps://, ldapi://, // and cldap:// (RFC1798, deprecated but used by Active Directory). // ldaps uses TLS/SSL, ldapi uses a Unix domain socket, and cldap uses connectionless LDAP. -// Signature: Client(ldapUrl,Realm) -// @param ldapUrl: string -// @param Realm: string -// @param Config: Config -// @return Client -// @throws error when the ldap url is invalid or connection fails +// Constructor: constructor(public ldapUrl: string, public realm: string, public config?: Config) func NewClient(call goja.ConstructorCall, runtime *goja.Runtime) *goja.Object { // setup nucleijs utils c := &Client{nj: utils.NewNucleiJS(runtime)} @@ -54,6 +76,8 @@ func NewClient(call goja.ConstructorCall, runtime *goja.Runtime) *goja.Object { ldapUrl, _ := c.nj.GetArg(call.Arguments, 0).(string) realm, _ := c.nj.GetArg(call.Arguments, 1).(string) c.cfg = utils.GetStructTypeSafe[Config](c.nj, call.Arguments, 2, Config{}) + c.Realm = realm + c.BaseDN = fmt.Sprintf("dc=%s", strings.Join(strings.Split(realm, "."), ",dc=")) // validate arguments c.nj.Require(ldapUrl != "", "ldap url cannot be empty") @@ -125,10 +149,12 @@ func NewClient(call goja.ConstructorCall, runtime *goja.Runtime) *goja.Object { // Authenticate authenticates with the ldap server using the given username and password // performs NTLMBind first and then Bind/UnauthenticatedBind if NTLMBind fails -// Signature: Authenticate(username, password) -// @param username: string -// @param password: string (can be empty for unauthenticated bind) -// @throws error if authentication fails +// @example +// ```javascript +// const ldap = require('nuclei/ldap'); +// const client = new ldap.Client('ldap://ldap.example.com', 'acme.com'); +// client.Authenticate('user', 'password'); +// ``` func (c *Client) Authenticate(username, password string) { c.nj.Require(c.conn != nil, "no existing connection") if c.BaseDN == "" { @@ -153,10 +179,12 @@ func (c *Client) Authenticate(username, password string) { } // AuthenticateWithNTLMHash authenticates with the ldap server using the given username and NTLM hash -// Signature: AuthenticateWithNTLMHash(username, hash) -// @param username: string -// @param hash: string -// @throws error if authentication fails +// @example +// ```javascript +// const ldap = require('nuclei/ldap'); +// const client = new ldap.Client('ldap://ldap.example.com', 'acme.com'); +// client.AuthenticateWithNTLMHash('pdtm', 'hash'); +// ``` func (c *Client) AuthenticateWithNTLMHash(username, hash string) { c.nj.Require(c.conn != nil, "no existing connection") if c.BaseDN == "" { @@ -169,10 +197,12 @@ func (c *Client) AuthenticateWithNTLMHash(username, hash string) { // Search accepts whatever filter and returns a list of maps having provided attributes // as keys and associated values mirroring the ones returned by ldap -// Signature: Search(filter, attributes...) -// @param filter: string -// @param attributes: ...string -// @return []map[string][]string +// @example +// ```javascript +// const ldap = require('nuclei/ldap'); +// const client = new ldap.Client('ldap://ldap.example.com', 'acme.com'); +// const results = client.Search('(objectClass=*)', 'cn', 'mail'); +// ``` func (c *Client) Search(filter string, attributes ...string) []map[string][]string { c.nj.Require(c.conn != nil, "no existing connection") @@ -209,16 +239,12 @@ func (c *Client) Search(filter string, attributes ...string) []map[string][]stri // AdvancedSearch accepts all values of search request type and return Ldap Entry // its up to user to handle the response -// Signature: AdvancedSearch(Scope, DerefAliases, SizeLimit, TimeLimit, TypesOnly, Filter, Attributes, Controls) -// @param Scope: int -// @param DerefAliases: int -// @param SizeLimit: int -// @param TimeLimit: int -// @param TypesOnly: bool -// @param Filter: string -// @param Attributes: []string -// @param Controls: []ldap.Control -// @return ldap.SearchResult +// @example +// ```javascript +// const ldap = require('nuclei/ldap'); +// const client = new ldap.Client('ldap://ldap.example.com', 'acme.com'); +// const results = client.AdvancedSearch(ldap.ScopeWholeSubtree, ldap.NeverDerefAliases, 0, 0, false, '(objectClass=*)', ['cn', 'mail'], []); +// ``` func (c *Client) AdvancedSearch( Scope, DerefAliases, SizeLimit, TimeLimit int, TypesOnly bool, @@ -236,20 +262,28 @@ func (c *Client) AdvancedSearch( return *res } -// Metadata is the metadata for ldap server. -type Metadata struct { - BaseDN string - Domain string - DefaultNamingContext string - DomainFunctionality string - ForestFunctionality string - DomainControllerFunctionality string - DnsHostName string -} +type ( + // Metadata is the metadata for ldap server. + // this is returned by CollectMetadata method + Metadata struct { + BaseDN string + Domain string + DefaultNamingContext string + DomainFunctionality string + ForestFunctionality string + DomainControllerFunctionality string + DnsHostName string + } +) // CollectLdapMetadata collects metadata from ldap server. -// Signature: CollectMetadata(domain, controller) -// @return Metadata +// @example +// ```javascript +// const ldap = require('nuclei/ldap'); +// const client = new ldap.Client('ldap://ldap.example.com', 'acme.com'); +// const metadata = client.CollectMetadata(); +// log(to_json(metadata)); +// ``` func (c *Client) CollectMetadata() Metadata { c.nj.Require(c.conn != nil, "no existing connection") var metadata Metadata @@ -297,6 +331,12 @@ func (c *Client) CollectMetadata() Metadata { } // close the ldap connection +// @example +// ```javascript +// const ldap = require('nuclei/ldap'); +// const client = new ldap.Client('ldap://ldap.example.com', 'acme.com'); +// client.Close(); +// ``` func (c *Client) Close() { c.conn.Close() } diff --git a/pkg/js/libs/ldap/utils.go b/pkg/js/libs/ldap/utils.go index 3c20a411c0..96a243bbc7 100644 --- a/pkg/js/libs/ldap/utils.go +++ b/pkg/js/libs/ldap/utils.go @@ -8,6 +8,12 @@ import ( ) // DecodeSID decodes a SID string +// @example +// ```javascript +// const ldap = require('nuclei/ldap'); +// const sid = ldap.DecodeSID('S-1-5-21-3623811015-3361044348-30300820-1013'); +// log(sid); +// ``` func DecodeSID(s string) string { b := []byte(s) revisionLvl := int(b[0]) @@ -41,6 +47,12 @@ func DecodeSID(s string) string { } // DecodeADTimestamp decodes an Active Directory timestamp +// @example +// ```javascript +// const ldap = require('nuclei/ldap'); +// const timestamp = ldap.DecodeADTimestamp('132036744000000000'); +// log(timestamp); +// ``` func DecodeADTimestamp(timestamp string) string { adtime, _ := strconv.ParseInt(timestamp, 10, 64) if (adtime == 9223372036854775807) || (adtime == 0) { @@ -52,7 +64,12 @@ func DecodeADTimestamp(timestamp string) string { } // DecodeZuluTimestamp decodes a Zulu timestamp -// example: 2021-08-25T14:00:00Z +// @example +// ```javascript +// const ldap = require('nuclei/ldap'); +// const timestamp = ldap.DecodeZuluTimestamp('2021-08-25T10:00:00Z'); +// log(timestamp); +// ``` func DecodeZuluTimestamp(timestamp string) string { zulu, err := time.Parse(time.RFC3339, timestamp) if err != nil { diff --git a/pkg/js/libs/mssql/mssql.go b/pkg/js/libs/mssql/mssql.go index 79fe58157b..18004f31ed 100644 --- a/pkg/js/libs/mssql/mssql.go +++ b/pkg/js/libs/mssql/mssql.go @@ -14,27 +14,41 @@ import ( "github.com/projectdiscovery/nuclei/v3/pkg/protocols/common/protocolstate" ) -// Client is a client for MS SQL database. -// -// Internally client uses denisenkom/go-mssqldb driver. -type MSSQLClient struct{} +type ( + // Client is a client for MS SQL database. + // Internally client uses denisenkom/go-mssqldb driver. + // @example + // ```javascript + // const mssql = require('nuclei/mssql'); + // const client = new mssql.Client(); + // ``` + MSSQLClient struct{} +) // Connect connects to MS SQL database using given credentials. -// // If connection is successful, it returns true. // If connection is unsuccessful, it returns false and error. -// // The connection is closed after the function returns. +// @example +// ```javascript +// const mssql = require('nuclei/mssql'); +// const client = new mssql.Client(); +// const connected = client.Connect('acme.com', 1433, 'username', 'password'); +// ``` func (c *MSSQLClient) Connect(host string, port int, username, password string) (bool, error) { return connect(host, port, username, password, "master") } // ConnectWithDB connects to MS SQL database using given credentials and database name. -// // If connection is successful, it returns true. // If connection is unsuccessful, it returns false and error. -// // The connection is closed after the function returns. +// @example +// ```javascript +// const mssql = require('nuclei/mssql'); +// const client = new mssql.Client(); +// const connected = client.ConnectWithDB('acme.com', 1433, 'username', 'password', 'master'); +// ``` func (c *MSSQLClient) ConnectWithDB(host string, port int, username, password, dbName string) (bool, error) { return connect(host, port, username, password, dbName) } @@ -82,9 +96,13 @@ func connect(host string, port int, username, password, dbName string) (bool, er } // IsMssql checks if the given host is running MS SQL database. -// // If the host is running MS SQL database, it returns true. // If the host is not running MS SQL database, it returns false. +// @example +// ```javascript +// const mssql = require('nuclei/mssql'); +// const isMssql = mssql.IsMssql('acme.com', 1433); +// ``` func (c *MSSQLClient) IsMssql(host string, port int) (bool, error) { if !protocolstate.IsHostAllowed(host) { // host is not valid according to network policy diff --git a/pkg/js/libs/mysql/mysql.go b/pkg/js/libs/mysql/mysql.go index b5911ae701..8bf8e5ec1c 100644 --- a/pkg/js/libs/mysql/mysql.go +++ b/pkg/js/libs/mysql/mysql.go @@ -16,15 +16,25 @@ import ( "github.com/projectdiscovery/nuclei/v3/pkg/protocols/common/protocolstate" ) -// MySQLClient is a client for MySQL database. -// -// Internally client uses go-sql-driver/mysql driver. -type MySQLClient struct{} +type ( + // MySQLClient is a client for MySQL database. + // Internally client uses go-sql-driver/mysql driver. + // @example + // ```javascript + // const mysql = require('nuclei/mysql'); + // const client = new mysql.Client(); + // ``` + MySQLClient struct{} +) // IsMySQL checks if the given host is running MySQL database. -// // If the host is running MySQL database, it returns true. // If the host is not running MySQL database, it returns false. +// @example +// ```javascript +// const mysql = require('nuclei/mysql'); +// const isMySQL = mysql.IsMySQL('acme.com', 3306); +// ``` func (c *MySQLClient) IsMySQL(host string, port int) (bool, error) { if !protocolstate.IsHostAllowed(host) { // host is not valid according to network policy @@ -48,10 +58,15 @@ func (c *MySQLClient) IsMySQL(host string, port int) (bool, error) { } // Connect connects to MySQL database using given credentials. -// // If connection is successful, it returns true. // If connection is unsuccessful, it returns false and error. // The connection is closed after the function returns. +// @example +// ```javascript +// const mysql = require('nuclei/mysql'); +// const client = new mysql.Client(); +// const connected = client.Connect('acme.com', 3306, 'username', 'password'); +// ``` func (c *MySQLClient) Connect(host string, port int, username, password string) (bool, error) { if !protocolstate.IsHostAllowed(host) { // host is not valid according to network policy @@ -71,19 +86,29 @@ func (c *MySQLClient) Connect(host string, port int, username, password string) return connectWithDSN(dsn) } -type MySQLInfo struct { - Host string `json:"host,omitempty"` - IP string `json:"ip"` - Port int `json:"port"` - Protocol string `json:"protocol"` - TLS bool `json:"tls"` - Transport string `json:"transport"` - Version string `json:"version,omitempty"` - Debug plugins.ServiceMySQL `json:"debug,omitempty"` - Raw string `json:"metadata"` -} +type ( + // MySQLInfo contains information about MySQL server. + // this is returned when fingerprint is successful + MySQLInfo struct { + Host string `json:"host,omitempty"` + IP string `json:"ip"` + Port int `json:"port"` + Protocol string `json:"protocol"` + TLS bool `json:"tls"` + Transport string `json:"transport"` + Version string `json:"version,omitempty"` + Debug plugins.ServiceMySQL `json:"debug,omitempty"` + Raw string `json:"metadata"` + } +) // returns MySQLInfo when fingerpint is successful +// @example +// ```javascript +// const mysql = require('nuclei/mysql'); +// const info = mysql.FingerprintMySQL('acme.com', 3306); +// log(to_json(info)); +// ``` func (c *MySQLClient) FingerprintMySQL(host string, port int) (MySQLInfo, error) { info := MySQLInfo{} if !protocolstate.IsHostAllowed(host) { @@ -120,10 +145,28 @@ func (c *MySQLClient) FingerprintMySQL(host string, port int) (MySQLInfo, error) // ConnectWithDSN connects to MySQL database using given DSN. // we override mysql dialer with fastdialer so it respects network policy +// If connection is successful, it returns true. +// @example +// ```javascript +// const mysql = require('nuclei/mysql'); +// const client = new mysql.Client(); +// const connected = client.ConnectWithDSN('username:password@tcp(acme.com:3306)/'); +// ``` func (c *MySQLClient) ConnectWithDSN(dsn string) (bool, error) { return connectWithDSN(dsn) } +// ExecuteQueryWithOpts connects to Mysql database using given credentials +// and executes a query on the db. +// @example +// ```javascript +// const mysql = require('nuclei/mysql'); +// const options = new mysql.MySQLOptions(); +// options.Host = 'acme.com'; +// options.Port = 3306; +// const result = mysql.ExecuteQueryWithOpts(options, 'SELECT * FROM users'); +// log(to_json(result)); +// ``` func (c *MySQLClient) ExecuteQueryWithOpts(opts MySQLOptions, query string) (*utils.SQLResult, error) { if !protocolstate.IsHostAllowed(opts.Host) { // host is not valid according to network policy @@ -160,6 +203,12 @@ func (c *MySQLClient) ExecuteQueryWithOpts(opts MySQLOptions, query string) (*ut // ExecuteQuery connects to Mysql database using given credentials // and executes a query on the db. +// @example +// ```javascript +// const mysql = require('nuclei/mysql'); +// const result = mysql.ExecuteQuery('acme.com', 3306, 'username', 'password', 'SELECT * FROM users'); +// log(to_json(result)); +// ``` func (c *MySQLClient) ExecuteQuery(host string, port int, username, password, query string) (*utils.SQLResult, error) { return c.ExecuteQueryWithOpts(MySQLOptions{ Host: host, @@ -172,6 +221,12 @@ func (c *MySQLClient) ExecuteQuery(host string, port int, username, password, qu // ExecuteQuery connects to Mysql database using given credentials // and executes a query on the db. +// @example +// ```javascript +// const mysql = require('nuclei/mysql'); +// const result = mysql.ExecuteQueryOnDB('acme.com', 3306, 'username', 'password', 'dbname', 'SELECT * FROM users'); +// log(to_json(result)); +// ``` func (c *MySQLClient) ExecuteQueryOnDB(host string, port int, username, password, dbname, query string) (*utils.SQLResult, error) { return c.ExecuteQueryWithOpts(MySQLOptions{ Host: host, diff --git a/pkg/js/libs/mysql/mysql_private.go b/pkg/js/libs/mysql/mysql_private.go index c0e47c04c4..dee0d323f4 100644 --- a/pkg/js/libs/mysql/mysql_private.go +++ b/pkg/js/libs/mysql/mysql_private.go @@ -8,20 +8,37 @@ import ( "strings" ) -// MySQLOptions defines the data source name (DSN) options required to connect to a MySQL database. -// along with other options like Timeout etc -type MySQLOptions struct { - Host string // Host is the host name or IP address of the MySQL server. - Port int // Port is the port number on which the MySQL server is listening. - Protocol string // Protocol is the protocol used to connect to the MySQL server (ex: "tcp"). - Username string // Username is the user name used to authenticate with the MySQL server. - Password string // Password is the password used to authenticate with the MySQL server. - DbName string // DbName is the name of the database to connect to on the MySQL server. - RawQuery string // QueryStr is the query string to append to the DSN (ex: "?tls=skip-verify"). - Timeout int // Timeout is the timeout in seconds for the connection to the MySQL server. -} +type ( + // MySQLOptions defines the data source name (DSN) options required to connect to a MySQL database. + // along with other options like Timeout etc + // @example + // ```javascript + // const mysql = require('nuclei/mysql'); + // const options = new mysql.MySQLOptions(); + // options.Host = 'acme.com'; + // options.Port = 3306; + // ``` + MySQLOptions struct { + Host string // Host is the host name or IP address of the MySQL server. + Port int // Port is the port number on which the MySQL server is listening. + Protocol string // Protocol is the protocol used to connect to the MySQL server (ex: "tcp"). + Username string // Username is the user name used to authenticate with the MySQL server. + Password string // Password is the password used to authenticate with the MySQL server. + DbName string // DbName is the name of the database to connect to on the MySQL server. + RawQuery string // QueryStr is the query string to append to the DSN (ex: "?tls=skip-verify"). + Timeout int // Timeout is the timeout in seconds for the connection to the MySQL server. + } +) // BuildDSN builds a MySQL data source name (DSN) from the given options. +// @example +// ```javascript +// const mysql = require('nuclei/mysql'); +// const options = new mysql.MySQLOptions(); +// options.Host = 'acme.com'; +// options.Port = 3306; +// const dsn = mysql.BuildDSN(options); +// ``` func BuildDSN(opts MySQLOptions) (string, error) { if opts.Host == "" || opts.Port <= 0 { return "", fmt.Errorf("invalid host or port") diff --git a/pkg/js/libs/net/net.go b/pkg/js/libs/net/net.go index 7d5b721719..7c2bb8b438 100644 --- a/pkg/js/libs/net/net.go +++ b/pkg/js/libs/net/net.go @@ -20,6 +20,11 @@ var ( // Open opens a new connection to the address with a timeout. // supported protocols: tcp, udp +// @example +// ```javascript +// const net = require('nuclei/net'); +// const conn = net.Open('tcp', 'acme.com:80'); +// ``` func Open(protocol, address string) (*NetConn, error) { conn, err := protocolstate.Dialer.Dial(context.TODO(), protocol, address) if err != nil { @@ -30,6 +35,11 @@ func Open(protocol, address string) (*NetConn, error) { // Open opens a new connection to the address with a timeout. // supported protocols: tcp, udp +// @example +// ```javascript +// const net = require('nuclei/net'); +// const conn = net.OpenTLS('tcp', 'acme.com:443'); +// ``` func OpenTLS(protocol, address string) (*NetConn, error) { config := &tls.Config{InsecureSkipVerify: true, MinVersion: tls.VersionTLS10} host, _, _ := net.SplitHostPort(address) @@ -45,19 +55,39 @@ func OpenTLS(protocol, address string) (*NetConn, error) { return &NetConn{conn: conn, timeout: defaultTimeout}, nil } -// NetConn is a connection to a remote host. -type NetConn struct { - conn net.Conn - timeout time.Duration -} +type ( + // NetConn is a connection to a remote host. + // this is returned/create by Open and OpenTLS functions. + // @example + // ```javascript + // const net = require('nuclei/net'); + // const conn = net.Open('tcp', 'acme.com:80'); + // ``` + NetConn struct { + conn net.Conn + timeout time.Duration + } +) // Close closes the connection. +// @example +// ```javascript +// const net = require('nuclei/net'); +// const conn = net.Open('tcp', 'acme.com:80'); +// conn.Close(); +// ``` func (c *NetConn) Close() error { err := c.conn.Close() return err } // SetTimeout sets read/write timeout for the connection (in seconds). +// @example +// ```javascript +// const net = require('nuclei/net'); +// const conn = net.Open('tcp', 'acme.com:80'); +// conn.SetTimeout(10); +// ``` func (c *NetConn) SetTimeout(value int) { c.timeout = time.Duration(value) * time.Second } @@ -77,6 +107,12 @@ func (c *NetConn) unsetDeadLine() { } // SendArray sends array data to connection +// @example +// ```javascript +// const net = require('nuclei/net'); +// const conn = net.Open('tcp', 'acme.com:80'); +// conn.SendArray(['hello', 'world']); +// ``` func (c *NetConn) SendArray(data []interface{}) error { c.setDeadLine() defer c.unsetDeadLine() @@ -92,6 +128,12 @@ func (c *NetConn) SendArray(data []interface{}) error { } // SendHex sends hex data to connection +// @example +// ```javascript +// const net = require('nuclei/net'); +// const conn = net.Open('tcp', 'acme.com:80'); +// conn.SendHex('68656c6c6f'); +// ``` func (c *NetConn) SendHex(data string) error { c.setDeadLine() defer c.unsetDeadLine() @@ -110,6 +152,12 @@ func (c *NetConn) SendHex(data string) error { } // Send sends data to the connection with a timeout. +// @example +// ```javascript +// const net = require('nuclei/net'); +// const conn = net.Open('tcp', 'acme.com:80'); +// conn.Send('hello'); +// ``` func (c *NetConn) Send(data string) error { c.setDeadLine() defer c.unsetDeadLine() @@ -126,6 +174,13 @@ func (c *NetConn) Send(data string) error { // Recv receives data from the connection with a timeout. // If N is 0, it will read all data sent by the server with 8MB limit. +// it tries to read until N bytes or timeout is reached. +// @example +// ```javascript +// const net = require('nuclei/net'); +// const conn = net.Open('tcp', 'acme.com:80'); +// const data = conn.Recv(1024); +// ``` func (c *NetConn) Recv(N int) ([]byte, error) { c.setDeadLine() defer c.unsetDeadLine() @@ -140,9 +195,39 @@ func (c *NetConn) Recv(N int) ([]byte, error) { return bin, nil } +// RecvPartial is similar to Recv but it does not perform full read instead +// it creates a buffer of N bytes and returns whatever is returned by the connection +// this is usually used when fingerprinting services to get initial bytes from the server. +// @example +// ```javascript +// const net = require('nuclei/net'); +// const conn = net.Open('tcp', 'acme.com:80'); +// const data = conn.RecvPartial(1024); +// log(`Received ${data.length} bytes from the server`) +// ``` +func (c *NetConn) RecvPartial(N int) ([]byte, error) { + c.setDeadLine() + defer c.unsetDeadLine() + if N == 0 { + N = 4096 + } + b := make([]byte, N) + n, err := c.conn.Read(b) + if err != nil { + return []byte{}, errorutil.NewWithErr(err).Msgf("failed to read %d bytes", N) + } + return b[:n], nil +} + // RecvString receives data from the connection with a timeout // output is returned as a string. // If N is 0, it will read all data sent by the server with 8MB limit. +// @example +// ```javascript +// const net = require('nuclei/net'); +// const conn = net.Open('tcp', 'acme.com:80'); +// const data = conn.RecvString(1024); +// ``` func (c *NetConn) RecvString(N int) (string, error) { bin, err := c.Recv(N) if err != nil { @@ -154,6 +239,12 @@ func (c *NetConn) RecvString(N int) (string, error) { // RecvHex receives data from the connection with a timeout // in hex format. // If N is 0,it will read all data sent by the server with 8MB limit. +// @example +// ```javascript +// const net = require('nuclei/net'); +// const conn = net.Open('tcp', 'acme.com:80'); +// const data = conn.RecvHex(1024); +// ``` func (c *NetConn) RecvHex(N int) (string, error) { bin, err := c.Recv(N) if err != nil { diff --git a/pkg/js/libs/oracle/oracle.go b/pkg/js/libs/oracle/oracle.go index d6bb48d1cb..bc4d1be518 100644 --- a/pkg/js/libs/oracle/oracle.go +++ b/pkg/js/libs/oracle/oracle.go @@ -11,16 +11,37 @@ import ( "github.com/projectdiscovery/nuclei/v3/pkg/protocols/common/protocolstate" ) -// OracleClient is a minimal Oracle client for nuclei scripts. -type OracleClient struct{} +type ( + // OracleClient is a minimal Oracle client for nuclei scripts. + // @example + // ```javascript + // const oracle = require('nuclei/oracle'); + // const client = new oracle.Client(); + // ``` + OracleClient struct{} +) -// IsOracleResponse is the response from the IsOracle function. -type IsOracleResponse struct { - IsOracle bool - Banner string -} +type ( + // IsOracleResponse is the response from the IsOracle function. + // this is returned by IsOracle function. + // @example + // ```javascript + // const oracle = require('nuclei/oracle'); + // const isOracle = oracle.IsOracle('acme.com', 1521); + // ``` + IsOracleResponse struct { + IsOracle bool + Banner string + } +) -// IsOracle checks if a host is running an Oracle server. +// IsOracle checks if a host is running an Oracle server +// @example +// ```javascript +// const oracle = require('nuclei/oracle'); +// const isOracle = oracle.IsOracle('acme.com', 1521); +// log(toJSON(isOracle)); +// ``` func (c *OracleClient) IsOracle(host string, port int) (IsOracleResponse, error) { resp := IsOracleResponse{} diff --git a/pkg/js/libs/pop3/pop3.go b/pkg/js/libs/pop3/pop3.go index f1ff7bb561..12f59b5b03 100644 --- a/pkg/js/libs/pop3/pop3.go +++ b/pkg/js/libs/pop3/pop3.go @@ -11,16 +11,38 @@ import ( "github.com/projectdiscovery/nuclei/v3/pkg/protocols/common/protocolstate" ) -// Pop3Client is a minimal POP3 client for nuclei scripts. -type Pop3Client struct{} +type ( + // Pop3Client is a minimal POP3 client for nuclei scripts. + // @example + // ```javascript + // const pop3 = require('nuclei/pop3'); + // const client = new pop3.Client(); + // ``` + Pop3Client struct{} +) -// IsPOP3Response is the response from the IsPOP3 function. -type IsPOP3Response struct { - IsPOP3 bool - Banner string -} +type ( + // IsPOP3Response is the response from the IsPOP3 function. + // this is returned by IsPOP3 function. + // @example + // ```javascript + // const pop3 = require('nuclei/pop3'); + // const isPOP3 = pop3.IsPOP3('acme.com', 110); + // log(toJSON(isPOP3)); + // ``` + IsPOP3Response struct { + IsPOP3 bool + Banner string + } +) // IsPOP3 checks if a host is running a POP3 server. +// @example +// ```javascript +// const pop3 = require('nuclei/pop3'); +// const isPOP3 = pop3.IsPOP3('acme.com', 110); +// log(toJSON(isPOP3)); +// ``` func (c *Pop3Client) IsPOP3(host string, port int) (IsPOP3Response, error) { resp := IsPOP3Response{} diff --git a/pkg/js/libs/postgres/postgres.go b/pkg/js/libs/postgres/postgres.go index e3c21bf609..e97ee7a55a 100644 --- a/pkg/js/libs/postgres/postgres.go +++ b/pkg/js/libs/postgres/postgres.go @@ -16,15 +16,25 @@ import ( "github.com/projectdiscovery/nuclei/v3/pkg/protocols/common/protocolstate" ) -// PGClient is a client for Postgres database. -// -// Internally client uses go-pg/pg driver. -type PGClient struct{} +type ( + // PGClient is a client for Postgres database. + // Internally client uses go-pg/pg driver. + // @example + // ```javascript + // const postgres = require('nuclei/postgres'); + // const client = new postgres.Client(); + // ``` + PGClient struct{} +) // IsPostgres checks if the given host and port are running Postgres database. -// // If connection is successful, it returns true. // If connection is unsuccessful, it returns false and error. +// @example +// ```javascript +// const postgres = require('nuclei/postgres'); +// const isPostgres = postgres.IsPostgres('acme.com', 5432); +// ``` func (c *PGClient) IsPostgres(host string, port int) (bool, error) { timeout := 10 * time.Second @@ -48,17 +58,29 @@ func (c *PGClient) IsPostgres(host string, port int) (bool, error) { } // Connect connects to Postgres database using given credentials. -// // If connection is successful, it returns true. // If connection is unsuccessful, it returns false and error. -// // The connection is closed after the function returns. +// @example +// ```javascript +// const postgres = require('nuclei/postgres'); +// const client = new postgres.Client(); +// const connected = client.Connect('acme.com', 5432, 'username', 'password'); +// ``` func (c *PGClient) Connect(host string, port int, username, password string) (bool, error) { return connect(host, port, username, password, "postgres") } // ExecuteQuery connects to Postgres database using given credentials and database name. // and executes a query on the db. +// If connection is successful, it returns the result of the query. +// @example +// ```javascript +// const postgres = require('nuclei/postgres'); +// const client = new postgres.Client(); +// const result = client.ExecuteQuery('acme.com', 5432, 'username', 'password', 'dbname', 'select * from users'); +// log(to_json(result)); +// ``` func (c *PGClient) ExecuteQuery(host string, port int, username, password, dbName, query string) (*utils.SQLResult, error) { if !protocolstate.IsHostAllowed(host) { // host is not valid according to network policy @@ -85,11 +107,15 @@ func (c *PGClient) ExecuteQuery(host string, port int, username, password, dbNam } // ConnectWithDB connects to Postgres database using given credentials and database name. -// // If connection is successful, it returns true. // If connection is unsuccessful, it returns false and error. -// // The connection is closed after the function returns. +// @example +// ```javascript +// const postgres = require('nuclei/postgres'); +// const client = new postgres.Client(); +// const connected = client.ConnectWithDB('acme.com', 5432, 'username', 'password', 'dbname'); +// ``` func (c *PGClient) ConnectWithDB(host string, port int, username, password, dbName string) (bool, error) { return connect(host, port, username, password, dbName) } diff --git a/pkg/js/libs/rdp/rdp.go b/pkg/js/libs/rdp/rdp.go index ff64b63e96..8df039d1a1 100644 --- a/pkg/js/libs/rdp/rdp.go +++ b/pkg/js/libs/rdp/rdp.go @@ -10,20 +10,41 @@ import ( "github.com/projectdiscovery/nuclei/v3/pkg/protocols/common/protocolstate" ) -// RDPClient is a client for rdp servers -type RDPClient struct{} +type ( + // RDPClient is a minimal RDP client for nuclei scripts. + // @example + // ```javascript + // const rdp = require('nuclei/rdp'); + // const client = new rdp.Client(); + // ``` + RDPClient struct{} +) -type IsRDPResponse struct { - IsRDP bool - OS string -} +type ( + // IsRDPResponse is the response from the IsRDP function. + // this is returned by IsRDP function. + // @example + // ```javascript + // const rdp = require('nuclei/rdp'); + // const isRDP = rdp.IsRDP('acme.com', 3389); + // log(toJSON(isRDP)); + // ``` + IsRDPResponse struct { + IsRDP bool + OS string + } +) // IsRDP checks if the given host and port are running rdp server. -// // If connection is successful, it returns true. // If connection is unsuccessful, it returns false and error. -// // The Name of the OS is also returned if the connection is successful. +// @example +// ```javascript +// const rdp = require('nuclei/rdp'); +// const isRDP = rdp.IsRDP('acme.com', 3389); +// log(toJSON(isRDP)); +// ``` func (c *RDPClient) IsRDP(host string, port int) (IsRDPResponse, error) { resp := IsRDPResponse{} @@ -46,13 +67,30 @@ func (c *RDPClient) IsRDP(host string, port int) (IsRDPResponse, error) { return resp, nil } -type CheckRDPAuthResponse struct { - PluginInfo *plugins.ServiceRDP - Auth bool -} +type ( + // CheckRDPAuthResponse is the response from the CheckRDPAuth function. + // this is returned by CheckRDPAuth function. + // @example + // ```javascript + // const rdp = require('nuclei/rdp'); + // const checkRDPAuth = rdp.CheckRDPAuth('acme.com', 3389); + // log(toJSON(checkRDPAuth)); + // ``` + CheckRDPAuthResponse struct { + PluginInfo *plugins.ServiceRDP + Auth bool + } +) // CheckRDPAuth checks if the given host and port are running rdp server // with authentication and returns their metadata. +// If connection is successful, it returns true. +// @example +// ```javascript +// const rdp = require('nuclei/rdp'); +// const checkRDPAuth = rdp.CheckRDPAuth('acme.com', 3389); +// log(toJSON(checkRDPAuth)); +// ``` func (c *RDPClient) CheckRDPAuth(host string, port int) (CheckRDPAuthResponse, error) { resp := CheckRDPAuthResponse{} diff --git a/pkg/js/libs/redis/redis.go b/pkg/js/libs/redis/redis.go index 686f9ff780..04f7145f93 100644 --- a/pkg/js/libs/redis/redis.go +++ b/pkg/js/libs/redis/redis.go @@ -13,6 +13,11 @@ import ( ) // GetServerInfo returns the server info for a redis server +// @example +// ```javascript +// const redis = require('nuclei/redis'); +// const info = redis.GetServerInfo('acme.com', 6379); +// ``` func GetServerInfo(host string, port int) (string, error) { if !protocolstate.IsHostAllowed(host) { // host is not valid according to network policy @@ -41,6 +46,11 @@ func GetServerInfo(host string, port int) (string, error) { } // Connect tries to connect redis server with password +// @example +// ```javascript +// const redis = require('nuclei/redis'); +// const connected = redis.Connect('acme.com', 6379, 'password'); +// ``` func Connect(host string, port int, password string) (bool, error) { if !protocolstate.IsHostAllowed(host) { // host is not valid according to network policy @@ -66,6 +76,11 @@ func Connect(host string, port int, password string) (bool, error) { } // GetServerInfoAuth returns the server info for a redis server +// @example +// ```javascript +// const redis = require('nuclei/redis'); +// const info = redis.GetServerInfoAuth('acme.com', 6379, 'password'); +// ``` func GetServerInfoAuth(host string, port int, password string) (string, error) { if !protocolstate.IsHostAllowed(host) { // host is not valid according to network policy @@ -94,6 +109,11 @@ func GetServerInfoAuth(host string, port int, password string) (string, error) { } // IsAuthenticated checks if the redis server requires authentication +// @example +// ```javascript +// const redis = require('nuclei/redis'); +// const isAuthenticated = redis.IsAuthenticated('acme.com', 6379); +// ``` func IsAuthenticated(host string, port int) (bool, error) { plugin := pluginsredis.REDISPlugin{} timeout := 5 * time.Second @@ -110,7 +130,12 @@ func IsAuthenticated(host string, port int) (bool, error) { return true, nil } -// RunLuaScript runs a lua script on +// RunLuaScript runs a lua script on the redis server +// @example +// ```javascript +// const redis = require('nuclei/redis'); +// const result = redis.RunLuaScript('acme.com', 6379, 'password', 'return redis.call("get", KEYS[1])'); +// ``` func RunLuaScript(host string, port int, password string, script string) (interface{}, error) { if !protocolstate.IsHostAllowed(host) { // host is not valid according to network policy diff --git a/pkg/js/libs/rsync/rsync.go b/pkg/js/libs/rsync/rsync.go index 267c1d5c76..a28dea2d79 100644 --- a/pkg/js/libs/rsync/rsync.go +++ b/pkg/js/libs/rsync/rsync.go @@ -11,16 +11,38 @@ import ( "github.com/projectdiscovery/nuclei/v3/pkg/protocols/common/protocolstate" ) -// RsyncClient is a minimal Rsync client for nuclei scripts. -type RsyncClient struct{} +type ( + // RsyncClient is a minimal Rsync client for nuclei scripts. + // @example + // ```javascript + // const rsync = require('nuclei/rsync'); + // const client = new rsync.Client(); + // ``` + RsyncClient struct{} +) -// IsRsyncResponse is the response from the IsRsync function. -type IsRsyncResponse struct { - IsRsync bool - Banner string -} +type ( + // IsRsyncResponse is the response from the IsRsync function. + // this is returned by IsRsync function. + // @example + // ```javascript + // const rsync = require('nuclei/rsync'); + // const isRsync = rsync.IsRsync('acme.com', 873); + // log(toJSON(isRsync)); + // ``` + IsRsyncResponse struct { + IsRsync bool + Banner string + } +) // IsRsync checks if a host is running a Rsync server. +// @example +// ```javascript +// const rsync = require('nuclei/rsync'); +// const isRsync = rsync.IsRsync('acme.com', 873); +// log(toJSON(isRsync)); +// ``` func (c *RsyncClient) IsRsync(host string, port int) (IsRsyncResponse, error) { resp := IsRsyncResponse{} diff --git a/pkg/js/libs/smb/smb.go b/pkg/js/libs/smb/smb.go index df9d28194b..da23c40833 100644 --- a/pkg/js/libs/smb/smb.go +++ b/pkg/js/libs/smb/smb.go @@ -11,17 +11,29 @@ import ( "github.com/zmap/zgrab2/lib/smb/smb" ) -// SMBClient is a client for SMB servers. -// -// Internally client uses github.com/zmap/zgrab2/lib/smb/smb driver. -// github.com/projectdiscovery/go-smb2 driver -type SMBClient struct{} +type ( + // SMBClient is a client for SMB servers. + // Internally client uses github.com/zmap/zgrab2/lib/smb/smb driver. + // github.com/projectdiscovery/go-smb2 driver + // @example + // ```javascript + // const smb = require('nuclei/smb'); + // const client = new smb.Client(); + // ``` + SMBClient struct{} +) // ConnectSMBInfoMode tries to connect to provided host and port // and discovery SMB information -// // Returns handshake log and error. If error is not nil, // state will be false +// @example +// ```javascript +// const smb = require('nuclei/smb'); +// const client = new smb.Client(); +// const info = client.ConnectSMBInfoMode('acme.com', 445); +// log(to_json(info)); +// ``` func (c *SMBClient) ConnectSMBInfoMode(host string, port int) (*smb.SMBLog, error) { if !protocolstate.IsHostAllowed(host) { // host is not valid according to network policy @@ -53,9 +65,15 @@ func (c *SMBClient) ConnectSMBInfoMode(host string, port int) (*smb.SMBLog, erro // ListSMBv2Metadata tries to connect to provided host and port // and list SMBv2 metadata. -// // Returns metadata and error. If error is not nil, // state will be false +// @example +// ```javascript +// const smb = require('nuclei/smb'); +// const client = new smb.Client(); +// const metadata = client.ListSMBv2Metadata('acme.com', 445); +// log(to_json(metadata)); +// ``` func (c *SMBClient) ListSMBv2Metadata(host string, port int) (*plugins.ServiceSMB, error) { if !protocolstate.IsHostAllowed(host) { // host is not valid according to network policy @@ -66,9 +84,19 @@ func (c *SMBClient) ListSMBv2Metadata(host string, port int) (*plugins.ServiceSM // ListShares tries to connect to provided host and port // and list shares by using given credentials. -// // Credentials cannot be blank. guest or anonymous credentials // can be used by providing empty password. +// @example +// ```javascript +// const smb = require('nuclei/smb'); +// const client = new smb.Client(); +// const shares = client.ListShares('acme.com', 445, 'username', 'password'); +// +// for (const share of shares) { +// log(share); +// } +// +// ``` func (c *SMBClient) ListShares(host string, port int, user, password string) ([]string, error) { if !protocolstate.IsHostAllowed(host) { // host is not valid according to network policy diff --git a/pkg/js/libs/smb/smbghost.go b/pkg/js/libs/smb/smbghost.go index 58f210fe4d..8e77a29319 100644 --- a/pkg/js/libs/smb/smbghost.go +++ b/pkg/js/libs/smb/smbghost.go @@ -19,6 +19,12 @@ const ( // DetectSMBGhost tries to detect SMBGhost vulnerability // by using SMBv3 compression feature. +// If the host is vulnerable, it returns true. +// @example +// ```javascript +// const smb = require('nuclei/smb'); +// const isSMBGhost = smb.DetectSMBGhost('acme.com', 445); +// ``` func (c *SMBClient) DetectSMBGhost(host string, port int) (bool, error) { if !protocolstate.IsHostAllowed(host) { // host is not valid according to network policy diff --git a/pkg/js/libs/smtp/msg.go b/pkg/js/libs/smtp/msg.go index 58d263c179..ceabbfea68 100644 --- a/pkg/js/libs/smtp/msg.go +++ b/pkg/js/libs/smtp/msg.go @@ -7,41 +7,79 @@ import ( "strings" ) -// SMTPMessage is a simple smtp message builder -type SMTPMessage struct { - from string - to []string - sub string - msg []byte - user string - pass string -} +type ( + // SMTPMessage is a message to be sent over SMTP + // @example + // ```javascript + // const smtp = require('nuclei/smtp'); + // const message = new smtp.SMTPMessage(); + // message.From('xyz@projectdiscovery.io'); + // ``` + SMTPMessage struct { + from string + to []string + sub string + msg []byte + user string + pass string + } +) // From adds the from field to the message +// @example +// ```javascript +// const smtp = require('nuclei/smtp'); +// const message = new smtp.SMTPMessage(); +// message.From('xyz@projectdiscovery.io'); +// ``` func (s *SMTPMessage) From(email string) *SMTPMessage { s.from = email return s } // To adds the to field to the message +// @example +// ```javascript +// const smtp = require('nuclei/smtp'); +// const message = new smtp.SMTPMessage(); +// message.To('xyz@projectdiscovery.io'); +// ``` func (s *SMTPMessage) To(email string) *SMTPMessage { s.to = append(s.to, email) return s } // Subject adds the subject field to the message +// @example +// ```javascript +// const smtp = require('nuclei/smtp'); +// const message = new smtp.SMTPMessage(); +// message.Subject('hello'); +// ``` func (s *SMTPMessage) Subject(sub string) *SMTPMessage { s.sub = sub return s } // Body adds the message body to the message +// @example +// ```javascript +// const smtp = require('nuclei/smtp'); +// const message = new smtp.SMTPMessage(); +// message.Body('hello'); +// ``` func (s *SMTPMessage) Body(msg []byte) *SMTPMessage { s.msg = msg return s } // Auth when called authenticates using username and password before sending the message +// @example +// ```javascript +// const smtp = require('nuclei/smtp'); +// const message = new smtp.SMTPMessage(); +// message.Auth('username', 'password'); +// ``` func (s *SMTPMessage) Auth(username, password string) *SMTPMessage { s.user = username s.pass = password @@ -49,6 +87,16 @@ func (s *SMTPMessage) Auth(username, password string) *SMTPMessage { } // String returns the string representation of the message +// @example +// ```javascript +// const smtp = require('nuclei/smtp'); +// const message = new smtp.SMTPMessage(); +// message.From('xyz@projectdiscovery.io'); +// message.To('xyz2@projectdiscoveyr.io'); +// message.Subject('hello'); +// message.Body('hello'); +// log(message.String()); +// ``` func (s *SMTPMessage) String() string { var buff bytes.Buffer tw := textproto.NewWriter(bufio.NewWriter(&buff)) diff --git a/pkg/js/libs/smtp/smtp.go b/pkg/js/libs/smtp/smtp.go index 11659076e4..ff74847762 100644 --- a/pkg/js/libs/smtp/smtp.go +++ b/pkg/js/libs/smtp/smtp.go @@ -14,16 +14,37 @@ import ( pluginsmtp "github.com/praetorian-inc/fingerprintx/pkg/plugins/services/smtp" ) -// SMTPClient is a minimal SMTP client for nuclei scripts. -type SMTPClient struct{} +type ( + // SMTPClient is a minimal SMTP client for nuclei scripts. + // @example + // ```javascript + // const smtp = require('nuclei/smtp'); + // const client = new smtp.Client(); + // ``` + SMTPClient struct{} +) -// IsSMTPResponse is the response from the IsSMTP function. -type IsSMTPResponse struct { - IsSMTP bool - Banner string -} +type ( + // IsSMTPResponse is the response from the IsSMTP function. + // @example + // ```javascript + // const smtp = require('nuclei/smtp'); + // const isSMTP = smtp.IsSMTP('acme.com', 25); + // log(toJSON(isSMTP)); + // ``` + IsSMTPResponse struct { + IsSMTP bool + Banner string + } +) // IsSMTP checks if a host is running a SMTP server. +// @example +// ```javascript +// const smtp = require('nuclei/smtp'); +// const isSMTP = smtp.IsSMTP('acme.com', 25); +// log(toJSON(isSMTP)); +// ``` func (c *SMTPClient) IsSMTP(host string, port int) (IsSMTPResponse, error) { resp := IsSMTPResponse{} @@ -47,6 +68,17 @@ func (c *SMTPClient) IsSMTP(host string, port int) (IsSMTPResponse, error) { return resp, nil } +// IsOpenRelay checks if a host is an open relay. +// @example +// ```javascript +// const smtp = require('nuclei/smtp'); +// const message = new smtp.SMTPMessage(); +// message.From('xyz@projectdiscovery.io'); +// message.To('xyz2@projectdiscoveyr.io'); +// message.Subject('hello'); +// message.Body('hello'); +// const isRelay = smtp.IsOpenRelay('acme.com', 25, message); +// ``` func (c *SMTPClient) IsOpenRelay(host string, port int, msg *SMTPMessage) (bool, error) { if !protocolstate.IsHostAllowed(host) { return false, protocolstate.ErrHostDenied.Msgf(host) @@ -95,6 +127,16 @@ func (c *SMTPClient) IsOpenRelay(host string, port int, msg *SMTPMessage) (bool, } // SendMail sends an email using the SMTP protocol. +// @example +// ```javascript +// const smtp = require('nuclei/smtp'); +// const message = new smtp.SMTPMessage(); +// message.From('xyz@projectdiscovery.io'); +// message.To('xyz2@projectdiscoveyr.io'); +// message.Subject('hello'); +// message.Body('hello'); +// const isSent = smtp.SendMail('acme.com', 25, message); +// ``` func (c *SMTPClient) SendMail(host string, port string, msg *SMTPMessage) (bool, error) { if !protocolstate.IsHostAllowed(host) { return false, protocolstate.ErrHostDenied.Msgf(host) diff --git a/pkg/js/libs/ssh/ssh.go b/pkg/js/libs/ssh/ssh.go index 24945f915e..e2f2793f77 100644 --- a/pkg/js/libs/ssh/ssh.go +++ b/pkg/js/libs/ssh/ssh.go @@ -10,24 +10,41 @@ import ( "github.com/zmap/zgrab2/lib/ssh" ) -// SSHClient is a client for SSH servers. -// -// Internally client uses github.com/zmap/zgrab2/lib/ssh driver. -type SSHClient struct { - Connection *ssh.Client - timeout time.Duration -} +type ( + // SSHClient is a client for SSH servers. + // Internally client uses github.com/zmap/zgrab2/lib/ssh driver. + // @example + // ```javascript + // const ssh = require('nuclei/ssh'); + // const client = new ssh.Client(); + // ``` + SSHClient struct { + connection *ssh.Client + timeout time.Duration + } +) // SetTimeout sets the timeout for the SSH connection in seconds +// @example +// ```javascript +// const ssh = require('nuclei/ssh'); +// const client = new ssh.Client(); +// client.SetTimeout(10); +// ``` func (c *SSHClient) SetTimeout(sec int) { c.timeout = time.Duration(sec) * time.Second } // Connect tries to connect to provided host and port // with provided username and password with ssh. -// // Returns state of connection and error. If error is not nil, // state will be false +// @example +// ```javascript +// const ssh = require('nuclei/ssh'); +// const client = new ssh.Client(); +// const connected = client.Connect('acme.com', 22, 'username', 'password'); +// ``` func (c *SSHClient) Connect(host string, port int, username, password string) (bool, error) { conn, err := connect(&connectOptions{ Host: host, @@ -38,16 +55,22 @@ func (c *SSHClient) Connect(host string, port int, username, password string) (b if err != nil { return false, err } - c.Connection = conn + c.connection = conn return true, nil } // ConnectWithKey tries to connect to provided host and port // with provided username and private_key. -// // Returns state of connection and error. If error is not nil, // state will be false +// @example +// ```javascript +// const ssh = require('nuclei/ssh'); +// const client = new ssh.Client(); +// const privateKey = `-----BEGIN RSA PRIVATE KEY----- ...`; +// const connected = client.ConnectWithKey('acme.com', 22, 'username', privateKey); +// ``` func (c *SSHClient) ConnectWithKey(host string, port int, username, key string) (bool, error) { conn, err := connect(&connectOptions{ Host: host, @@ -59,19 +82,24 @@ func (c *SSHClient) ConnectWithKey(host string, port int, username, key string) if err != nil { return false, err } - c.Connection = conn + c.connection = conn return true, nil } // ConnectSSHInfoMode tries to connect to provided host and port // with provided host and port -// // Returns HandshakeLog and error. If error is not nil, // state will be false -// // HandshakeLog is a struct that contains information about the // ssh connection +// @example +// ```javascript +// const ssh = require('nuclei/ssh'); +// const client = new ssh.Client(); +// const info = client.ConnectSSHInfoMode('acme.com', 22); +// log(to_json(info)); +// ``` func (c *SSHClient) ConnectSSHInfoMode(host string, port int) (*ssh.HandshakeLog, error) { return connectSSHInfoMode(&connectOptions{ Host: host, @@ -81,16 +109,22 @@ func (c *SSHClient) ConnectSSHInfoMode(host string, port int) (*ssh.HandshakeLog // Run tries to open a new SSH session, then tries to execute // the provided command in said session -// // Returns string and error. If error is not nil, // state will be false -// // The string contains the command output +// @example +// ```javascript +// const ssh = require('nuclei/ssh'); +// const client = new ssh.Client(); +// client.Connect('acme.com', 22, 'username', 'password'); +// const output = client.Run('id'); +// log(output); +// ``` func (c *SSHClient) Run(cmd string) (string, error) { - if c.Connection == nil { + if c.connection == nil { return "", errorutil.New("no connection") } - session, err := c.Connection.NewSession() + session, err := c.connection.NewSession() if err != nil { return "", err } @@ -105,11 +139,17 @@ func (c *SSHClient) Run(cmd string) (string, error) { } // Close closes the SSH connection and destroys the client -// // Returns the success state and error. If error is not nil, // state will be false +// @example +// ```javascript +// const ssh = require('nuclei/ssh'); +// const client = new ssh.Client(); +// client.Connect('acme.com', 22, 'username', 'password'); +// const closed = client.Close(); +// ``` func (c *SSHClient) Close() (bool, error) { - if err := c.Connection.Close(); err != nil { + if err := c.connection.Close(); err != nil { return false, err } return true, nil diff --git a/pkg/js/libs/structs/structs.go b/pkg/js/libs/structs/structs.go index 5e66d786df..650d2a3d7b 100644 --- a/pkg/js/libs/structs/structs.go +++ b/pkg/js/libs/structs/structs.go @@ -11,6 +11,11 @@ import ( // The byte slice must contain not less the amount of data required by the format // (len(msg) must more or equal CalcSize(format)). // Ex: structs.Unpack(">I", buff[:nb]) +// @example +// ```javascript +// const structs = require('nuclei/structs'); +// const result = structs.Unpack('H', [0]); +// ``` func Unpack(format string, msg []byte) ([]interface{}, error) { return gostruct.UnPack(buildFormatSliceFromStringFormat(format), msg) } @@ -18,6 +23,11 @@ func Unpack(format string, msg []byte) ([]interface{}, error) { // StructsPack returns a byte slice containing the values of msg slice packed according to the given format. // The items of msg slice must match the values required by the format exactly. // Ex: structs.pack("H", 0) +// @example +// ```javascript +// const structs = require('nuclei/structs'); +// const packed = structs.Pack('H', [0]); +// ``` func Pack(formatStr string, msg interface{}) ([]byte, error) { var args []interface{} switch v := msg.(type) { @@ -44,6 +54,12 @@ func Pack(formatStr string, msg interface{}) ([]byte, error) { } // StructsCalcSize returns the number of bytes needed to pack the values according to the given format. +// Ex: structs.CalcSize("H") +// @example +// ```javascript +// const structs = require('nuclei/structs'); +// const size = structs.CalcSize('H'); +// ``` func StructsCalcSize(format string) (int, error) { return gostruct.CalcSize(buildFormatSliceFromStringFormat(format)) } diff --git a/pkg/js/libs/telnet/telnet.go b/pkg/js/libs/telnet/telnet.go index 5cf58a51c6..6c620ef277 100644 --- a/pkg/js/libs/telnet/telnet.go +++ b/pkg/js/libs/telnet/telnet.go @@ -11,16 +11,38 @@ import ( "github.com/projectdiscovery/nuclei/v3/pkg/protocols/common/protocolstate" ) -// TelnetClient is a minimal Telnet client for nuclei scripts. -type TelnetClient struct{} +type ( + // TelnetClient is a minimal Telnet client for nuclei scripts. + // @example + // ```javascript + // const telnet = require('nuclei/telnet'); + // const client = new telnet.Client(); + // ``` + TelnetClient struct{} +) -// IsTelnetResponse is the response from the IsTelnet function. -type IsTelnetResponse struct { - IsTelnet bool - Banner string -} +type ( + // IsTelnetResponse is the response from the IsTelnet function. + // this is returned by IsTelnet function. + // @example + // ```javascript + // const telnet = require('nuclei/telnet'); + // const isTelnet = telnet.IsTelnet('acme.com', 23); + // log(toJSON(isTelnet)); + // ``` + IsTelnetResponse struct { + IsTelnet bool + Banner string + } +) // IsTelnet checks if a host is running a Telnet server. +// @example +// ```javascript +// const telnet = require('nuclei/telnet'); +// const isTelnet = telnet.IsTelnet('acme.com', 23); +// log(toJSON(isTelnet)); +// ``` func (c *TelnetClient) IsTelnet(host string, port int) (IsTelnetResponse, error) { resp := IsTelnetResponse{} diff --git a/pkg/js/libs/vnc/vnc.go b/pkg/js/libs/vnc/vnc.go index e5857580bf..f2747c3a53 100644 --- a/pkg/js/libs/vnc/vnc.go +++ b/pkg/js/libs/vnc/vnc.go @@ -11,18 +11,39 @@ import ( "github.com/projectdiscovery/nuclei/v3/pkg/protocols/common/protocolstate" ) -// VNCClient is a minimal VNC client for nuclei scripts. -type VNCClient struct{} +type ( + // VNCClient is a minimal VNC client for nuclei scripts. + // @example + // ```javascript + // const vnc = require('nuclei/vnc'); + // const client = new vnc.Client(); + // ``` + VNCClient struct{} +) -// IsVNCResponse is the response from the IsVNC function. -type IsVNCResponse struct { - IsVNC bool - Banner string -} +type ( + // IsVNCResponse is the response from the IsVNC function. + // @example + // ```javascript + // const vnc = require('nuclei/vnc'); + // const isVNC = vnc.IsVNC('acme.com', 5900); + // log(toJSON(isVNC)); + // ``` + IsVNCResponse struct { + IsVNC bool + Banner string + } +) // IsVNC checks if a host is running a VNC server. // It returns a boolean indicating if the host is running a VNC server // and the banner of the VNC server. +// @example +// ```javascript +// const vnc = require('nuclei/vnc'); +// const isVNC = vnc.IsVNC('acme.com', 5900); +// log(toJSON(isVNC)); +// ``` func (c *VNCClient) IsVNC(host string, port int) (IsVNCResponse, error) { resp := IsVNCResponse{}