samba-client
Advanced tools
Comparing version
@@ -10,3 +10,2 @@ "use strict"; | ||
address: process.argv[2], | ||
username: "Guest", | ||
}); | ||
@@ -17,9 +16,6 @@ | ||
await client.mkdir("test-directory"); | ||
console.log(`created test directory on samba share at ${client.address}`); | ||
const list = await client.listFiles("eflex", ".txt"); | ||
console.log(`found these files: ${list}`); | ||
await client.mkdir("test-directory"); | ||
await client.mkdir("test directory"); | ||
console.log(`created test directory on samba share at ${client.address}`); | ||
@@ -41,8 +37,6 @@ | ||
} | ||
await fs.unlink(testFile); | ||
} | ||
process.on("exit", function () { | ||
fs.unlinkSync(testFile); | ||
}); | ||
run(); |
156
index.js
"use strict"; | ||
const exec = require("child_process").exec; | ||
const util = require("util"); | ||
const execa = require("execa"); | ||
const p = require("path"); | ||
@@ -14,5 +13,4 @@ | ||
function wrap(str) { | ||
return "'" + str + "'"; | ||
} | ||
const getCleanedSmbClientArgs = (args) => | ||
args.map((arg) => `"${arg.replace(singleSlash, "\\")}"`).join(" "); | ||
@@ -22,4 +20,4 @@ class SambaClient { | ||
this.address = options.address; | ||
this.username = wrap(options.username || "guest"); | ||
this.password = options.password ? wrap(options.password) : null; | ||
this.username = options.username || "guest"; | ||
this.password = options.password; | ||
this.domain = options.domain; | ||
@@ -33,21 +31,17 @@ this.port = options.port; | ||
getFile(path, destination, workingDir) { | ||
const fileName = path.replace(singleSlash, "\\"); | ||
const cmdArgs = util.format("%s %s", fileName, destination); | ||
return this.execute("get", cmdArgs, workingDir); | ||
async getFile(path, destination, workingDir) { | ||
return await this.execute("get", [path, destination], workingDir); | ||
} | ||
sendFile(path, destination) { | ||
async sendFile(path, destination) { | ||
const workingDir = p.dirname(path); | ||
const fileName = p.basename(path).replace(singleSlash, "\\"); | ||
const cmdArgs = util.format( | ||
"%s %s", | ||
fileName, | ||
destination.replace(singleSlash, "\\") | ||
return await this.execute( | ||
"put", | ||
[p.basename(path), destination], | ||
workingDir | ||
); | ||
return this.execute("put", cmdArgs, workingDir); | ||
} | ||
deleteFile(fileName) { | ||
return this.execute("del", fileName, ""); | ||
async deleteFile(fileName) { | ||
return await this.execute("del", [fileName], ""); | ||
} | ||
@@ -57,8 +51,7 @@ | ||
try { | ||
const cmdArgs = util.format("%s*%s", fileNamePrefix, fileNameSuffix); | ||
const cmdArgs = `${fileNamePrefix}*${fileNameSuffix}`; | ||
const allOutput = await this.execute("dir", cmdArgs, ""); | ||
const fileList = []; | ||
const lines = allOutput.split("\n"); | ||
for (let i = 0; i < lines.length; i++) { | ||
const line = lines[i].toString().trim(); | ||
for (let line of allOutput.split("\n")) { | ||
line = line.toString().trim(); | ||
if (line.startsWith(fileNamePrefix)) { | ||
@@ -82,16 +75,8 @@ const parsed = line.substring( | ||
mkdir(remotePath, cwd) { | ||
return this.execute( | ||
"mkdir", | ||
remotePath.replace(singleSlash, "\\"), | ||
cwd !== null && cwd !== undefined ? cwd : __dirname | ||
); | ||
async mkdir(remotePath, cwd) { | ||
return await this.execute("mkdir", [remotePath], cwd || __dirname); | ||
} | ||
dir(remotePath, cwd) { | ||
return this.execute( | ||
"dir", | ||
remotePath.replace(singleSlash, "\\"), | ||
cwd !== null && cwd !== undefined ? cwd : __dirname | ||
); | ||
async dir(remotePath, cwd) { | ||
return await this.execute("dir", [remotePath], cwd || __dirname); | ||
} | ||
@@ -120,8 +105,10 @@ | ||
const remoteDirContents = await this.dir(remotePath); | ||
for (const content of remoteDirContents.matchAll(/\s?(.+)\s{2}/g)) { | ||
for (const content of remoteDirContents.matchAll( | ||
/\s*(.+?)\s{6,}(.)\s+([0-9]+)\s{2}(.+)/g | ||
)) { | ||
remoteDirList.push({ | ||
name: content[1].match(/\s?(.*?)\s/)[1], | ||
type: content[1].match(/(.)\s+[0-9]/)[1], | ||
size: content[1].match(/.\s+([0-9]+)/)[1], | ||
modifyTime: content[1].match(/[0-9]+\s+(.+)/)[1], | ||
name: content[1], | ||
type: content[2], | ||
size: parseInt(content[3]), | ||
modifyTime: new Date(content[4] + "Z"), | ||
}); | ||
@@ -132,5 +119,9 @@ } | ||
getSmbClientArgs(fullCmd) { | ||
const args = ["-U", this.username]; | ||
getSmbClientArgs(smbCommand, smbCommandArgs) { | ||
const args = []; | ||
if (this.username) { | ||
args.push("-U", this.username); | ||
} | ||
if (!this.password) { | ||
@@ -140,3 +131,7 @@ args.push("-N"); | ||
args.push("-c", fullCmd, this.address); | ||
let cleanedSmbArgs = smbCommandArgs; | ||
if (Array.isArray(smbCommandArgs)) { | ||
cleanedSmbArgs = getCleanedSmbClientArgs(smbCommandArgs); | ||
} | ||
args.push("-c", `${smbCommand} ${cleanedSmbArgs}`, this.address); | ||
@@ -164,53 +159,44 @@ if (this.password) { | ||
execute(cmd, cmdArgs, workingDir) { | ||
const fullCmd = wrap(util.format("%s %s", cmd, cmdArgs)); | ||
const command = [ | ||
"smbclient", | ||
this.getSmbClientArgs(fullCmd).join(" "), | ||
].join(" "); | ||
async execute(smbCommand, smbCommandArgs, workingDir) { | ||
const args = this.getSmbClientArgs(smbCommand, smbCommandArgs); | ||
const options = { | ||
all: true, | ||
cwd: workingDir || "", | ||
}; | ||
const maskCmd = this.maskCmd; | ||
return new Promise((resolve, reject) => { | ||
exec(command, options, function (err, stdout, stderr) { | ||
const allOutput = stdout + stderr; | ||
try { | ||
const { all } = await execa("smbclient", args, options); | ||
return all; | ||
} catch (error) { | ||
if (this.maskCmd) { | ||
error.message = error.all; | ||
error.shortMessage = error.all; | ||
} | ||
throw error; | ||
} | ||
} | ||
if (err) { | ||
// The error message by default contains the whole smbclient command that was run | ||
// This contains the username, password in plain text which can be a security risk | ||
// maskCmd option allows user to hide the command from the error message | ||
err.message = maskCmd ? allOutput : err.message + allOutput; | ||
return reject(err); | ||
} | ||
return resolve(allOutput); | ||
async getAllShares() { | ||
try { | ||
const { stdout } = await execa("smbtree", ["-U", "guest", "-N"], { | ||
all: true, | ||
}); | ||
}); | ||
} | ||
getAllShares() { | ||
const maskCmd = this.maskCmd; | ||
return new Promise((resolve, reject) => { | ||
exec("smbtree -U guest -N", {}, function (err, stdout, stderr) { | ||
const allOutput = stdout + stderr; | ||
if (err !== null) { | ||
err.message = maskCmd ? allOutput : err.message + allOutput; | ||
return reject(err); | ||
const shares = []; | ||
for (const line in stdout.split(/\r?\n/)) { | ||
const words = line.split(/\t/); | ||
if (words.length > 2 && words[2].match(/^\s*$/) !== null) { | ||
shares.append(words[2].trim()); | ||
} | ||
} | ||
const shares = []; | ||
for (const line in stdout.split(/\r?\n/)) { | ||
const words = line.split(/\t/); | ||
if (words.length > 2 && words[2].match(/^\s*$/) !== null) { | ||
shares.append(words[2].trim()); | ||
} | ||
} | ||
return resolve(shares); | ||
}); | ||
}); | ||
return shares; | ||
} catch (error) { | ||
if (this.maskCmd) { | ||
error.message = error.all; | ||
error.shortMessage = error.all; | ||
} | ||
throw error; | ||
} | ||
} | ||
@@ -217,0 +203,0 @@ } |
{ | ||
"name": "samba-client", | ||
"version": "3.4.0", | ||
"version": "4.0.0", | ||
"description": "wrapper for smbclient", | ||
@@ -28,4 +28,4 @@ "main": "index.js", | ||
"devDependencies": { | ||
"eslint": "^7.15.0", | ||
"eslint-config-prettier": "^7.0.0", | ||
"eslint": "^7.19.0", | ||
"eslint-config-prettier": "^7.2.0", | ||
"eslint-config-standard": "^16.0.2", | ||
@@ -36,3 +36,6 @@ "eslint-plugin-import": "^2.22.1", | ||
"prettier": "^2.2.1" | ||
}, | ||
"dependencies": { | ||
"execa": "^5.0.0" | ||
} | ||
} |
Deprecated
MaintenanceThe maintainer of the package marked it as deprecated. This could indicate that a single version should not be used, or that the package is no longer maintained and any new vulnerabilities will not be fixed.
Found 1 instance in 1 package
Shell access
Supply chain riskThis module accesses the system shell. Accessing the system shell increases the risk of executing arbitrary code.
Found 1 instance in 1 package
0
-100%0
-100%9516
-8.66%1
Infinity%207
-7.59%+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added