- run npm install on stager to recompile native modules
- provide modules based on package.json dependencies
- install npm on dev setup

Change-Id: I3e95aaf0982aea77fc280b58fcf965d1342b2ecf
This commit is contained in:
Maria Shaldybina 2012-03-01 17:25:37 -08:00
Родитель 2d9be87a6d
Коммит 92d7f606e7
42 изменённых файлов: 3514 добавлений и 23 удалений

Просмотреть файл

@ -8,7 +8,7 @@ gem 'nats', :require => 'nats/client'
# VCAP common components
gem 'vcap_common', :require => ['vcap/common', 'vcap/component']
gem 'vcap_logging', :require => ['vcap/logging']
gem 'vcap_staging', '~> 0.1.50'
gem 'vcap_staging', '~> 0.1.51'
gem 'cf-uaa-client', '>= 0.0.8'
# For queuing staging tasks

Просмотреть файл

@ -139,7 +139,7 @@ GEM
yajl-ruby (~> 0.8.3)
vcap_logging (1.0.0)
vcap_stager (0.1.14)
vcap_staging (0.1.50)
vcap_staging (0.1.51)
nokogiri (>= 1.4.4)
rake
rspec
@ -180,5 +180,5 @@ DEPENDENCIES
vcap_common
vcap_logging
vcap_stager (~> 0.1.14)
vcap_staging (~> 0.1.50)
vcap_staging (~> 0.1.51)
yajl-ruby (~> 0.8.3)

Двоичный файл не отображается.

Просмотреть файл

@ -5,11 +5,13 @@ runtimes:
version: '0.4.12'
description: 'Node.js'
executable: <%= File.join(node[:node04][:path], "bin", "node") %>
npm: <%= File.join(node[:node04][:npm][:path], "bin", "npm-cli.js") %>
default: true
- node06:
version: '0.6.8'
description: 'Node.js'
executable: <%= File.join(node[:node06][:path], "bin", "node") %>
npm: <%= File.join(node[:node06][:path], "bin", "npm") %>
app_servers:
detection:
- "*.js": '.'

Просмотреть файл

@ -2,3 +2,7 @@ include_attribute "deployment"
default[:node04][:version] = "0.4.12"
default[:node04][:path] = File.join(node[:deployment][:home], "deploy", "nodes", "node-#{node04[:version]}")
default[:node04][:source] = "http://nodejs.org/dist/node-v#{node04[:version]}.tar.gz"
default[:node04][:npm][:version] = "1.0.106"
default[:node04][:npm][:source] = "http://registry.npmjs.org/npm/-/npm-#{node[:node04][:npm][:version]}.tgz"
default[:node04][:npm][:path] = File.join(node[:deployment][:home], "deploy", "nodes", "npm-#{node[:node04][:npm][:version]}")

Просмотреть файл

@ -1,5 +1,5 @@
module NodeInstall
def cf_node_install(node_version, node_source, node_path)
def cf_node_install(node_version, node_source, node_path, node_npm=nil)
%w[ build-essential ].each do |pkg|
package pkg
end
@ -10,7 +10,6 @@ module NodeInstall
not_if { ::File.exists?(File.join("", "tmp", "node-v#{node_version}.tar.gz")) }
end
directory node_path do
owner node[:deployment][:user]
group node[:deployment][:group]
@ -33,10 +32,42 @@ module NodeInstall
::File.exists?(File.join(node_path, "bin", "node"))
end
end
minimal_npm_bundled_node_version = "0.6.3"
if Gem::Version.new(node_version) < Gem::Version.new(minimal_npm_bundled_node_version)
remote_file File.join("", "tmp", "npm-#{node_npm[:version]}.tgz") do
owner node[:deployment][:user]
source node_npm[:source]
not_if { ::File.exists?(File.join("", "tmp", "npm-#{node_npm[:version]}.tgz")) }
end
directory node_npm[:path] do
owner node[:deployment][:user]
group node[:deployment][:group]
mode "0755"
recursive true
action :create
end
bash "Install npm version " + node_npm[:version] do
cwd File.join("", "tmp")
user node[:deployment][:user]
code <<-EOH
package=npm-#{node_npm[:version]}
mkdir -p $package
tar xzf ${package}.tgz --directory=#{node_npm[:path]} --strip-components=1
EOH
not_if do
::File.exists?(File.join(node_npm[:path], "bin", "npm-cli.js"))
end
end
end
end
end
class Chef::Recipe
include NodeInstall
end

Просмотреть файл

@ -1,5 +1,6 @@
node_version = node[:node04][:version]
node_source = node[:node04][:source]
node_path = node[:node04][:path]
node_npm = node[:node04][:npm]
cf_node_install(node_version, node_source, node_path)
cf_node_install(node_version, node_source, node_path, node_npm)

Просмотреть файл

@ -7,7 +7,7 @@ gem 'yajl-ruby', '>= 0.7.9'
gem 'vcap_common', '~> 1.0.8'
gem 'vcap_logging', '>= 0.1.3'
gem 'vcap_staging', '~> 0.1.49'
gem 'vcap_staging', '~> 0.1.51'
group :test do
gem 'rspec'

Просмотреть файл

@ -44,7 +44,7 @@ GEM
yajl-ruby (~> 0.8.3)
vcap_logging (1.0.0)
rake
vcap_staging (0.1.50)
vcap_staging (0.1.51)
nokogiri (>= 1.4.4)
rake
rspec
@ -68,6 +68,6 @@ DEPENDENCIES
sinatra
vcap_common (~> 1.0.8)
vcap_logging (>= 0.1.3)
vcap_staging (~> 0.1.49)
vcap_staging (~> 0.1.51)
webmock
yajl-ruby (>= 0.7.9)

Двоичный файл не отображается.

Просмотреть файл

@ -1,7 +1,7 @@
PATH
remote: .
specs:
vcap_staging (0.1.50)
vcap_staging (0.1.51)
nokogiri (>= 1.4.4)
rake
rspec

Просмотреть файл

@ -59,6 +59,7 @@ class StagingPlugin
begin
# NOTE - Make others as needed for other kinds of package managers.
FileUtils.mkdir_p File.join(staging_cache_dir, 'gems')
FileUtils.mkdir_p File.join(staging_cache_dir, "node_modules")
# TODO - Validate java runtimes as well.
check_ruby_runtimes
rescue => ex

Просмотреть файл

@ -0,0 +1,32 @@
require "fileutils"
class NpmCache
def initialize(directory, logger)
@cached_dir = File.join(directory, "npm_cache")
@logger = logger
FileUtils.mkdir_p(@cached_dir)
end
def put(source, name, version)
return unless source && File.exists?(source)
dir = File.join(@cached_dir, name, version)
package_path = File.join(dir, "package")
return if File.exists?(package_path)
FileUtils.mkdir_p(File.dirname(package_path))
begin
File.rename(source, package_path)
rescue => e
@logger.debug("Failed putting into cache: #{e}")
return nil
end
package_path
end
def get(name, version)
dir = File.join(@cached_dir, name, version)
return nil unless File.exists?(File.join(dir, ".done"))
package_path = File.join(dir, "package")
return package_path if File.directory?(package_path)
end
end

Просмотреть файл

@ -0,0 +1,52 @@
class NpmHelper
attr_accessor :npm_version
def initialize(node_path, node_version, npm_path)
@node_path = node_path
@node_version = node_version
@npm_path = npm_path
@npm_version = get_npm_version
end
def get_npm_version
version = `#{npm_cmd} -v 2>&1`
return version.chomp if $?.exitstatus == 0
end
def node_safe_env
env_vars = [ "HTTP_PROXY", "HTTPS_PROXY", "NO_PROXY", "C_INCLUDE_PATH", "LIBRARY_PATH" ]
safe_env = env_vars.map { |e| "#{e}='#{ENV[e]}'" }.join(" ")
safe_env << " LANG=en_US.UTF-8 LC_ALL=en_US.UTF-8"
safe_env << " PATH=#{File.dirname(@node_path)}:$PATH"
safe_env
end
def npm_cmd
if @npm_path =~ /\.js$/
"#{node_safe_env} #{@node_path} #{@npm_path}"
else
"#{node_safe_env} #{@npm_path}"
end
end
def rebuild_cmd(where)
"#{npm_cmd} rebuild --prefix #{where} --production true " +
"--color false --loglevel error"
end
def install_cmd(package, where, cache_dir, tmp_dir, uid, gid)
cmd = "#{npm_cmd} install #{package} --prefix #{where} --production true "
cmd += "--color false --loglevel error --non-global true --force true "
cmd += "--user #{uid} " if uid
cmd += "--group #{gid} " if gid
cmd += "--cache #{cache_dir} --tmp #{tmp_dir} --node_version #{@node_version}"
end
def versioner_cmd(package_link)
versioner_path = File.expand_path("../../resources/versioner/versioner.js", __FILE__)
"#{node_safe_env} #{@node_path} #{versioner_path} " +
"--package=#{package_link} --node-version=#{@node_version} " +
"--npm-version=#{@npm_version}"
end
end

Просмотреть файл

@ -0,0 +1,154 @@
require "fileutils"
class NpmPackage
def initialize(name, version, modules_dir, secure_uid, secure_gid,
npm_helper, logger, cache)
@name = name.chomp
@version = version.chomp
@resolved_version = nil
@npm_helper = npm_helper
@secure_uid = secure_uid
@secure_gid = secure_gid
@logger = logger
@cache = cache
@modules_dir = modules_dir
end
def install
if url_provided?
@logger.warn("Failed installing package #{@name}. URLs are not supported")
return nil
end
resolved = resolved_version_data
unless resolved.is_a?(Hash) && resolved["version"]
log_name = @version.empty? ? @name : "#{@name}@#{@version}"
@logger.warn("Failed getting the requested package: #{log_name}")
return nil
end
@resolved_version = resolved["version"]
cached = @cache.get(@name, @resolved_version)
if cached
copy_to_app(cached)
else
installed = safe_install
if installed
copy_to_app(installed)
@cache.put(installed, @name, @resolved_version)
end
end
end
def copy_to_app(source)
return unless source && File.exist?(source)
dst_dir = File.join(@modules_dir, @name)
FileUtils.rm_rf(dst_dir)
FileUtils.mkdir_p(dst_dir)
`cp -a #{source}/* #{dst_dir}`
$?.exitstatus == 0
end
# This is done in a similar to ruby gems way until PackageCache is available
def safe_install
tmp_dir = Dir.mktmpdir
at_exit do
user = `whoami`.chomp
`sudo /bin/chown -R #{user} #{tmp_dir}` if @secure_uid
FileUtils.rm_rf(tmp_dir)
end
install_dir = File.join(tmp_dir, 'install')
npm_tmp_dir = File.join(tmp_dir, 'tmp')
npm_cache_dir = File.join(tmp_dir, 'cache')
begin
Dir.mkdir(install_dir)
Dir.mkdir(npm_tmp_dir)
Dir.mkdir(npm_cache_dir)
rescue => e
@logger.error("Failed creating npm install directories: #{e}")
return nil
end
if @secure_uid
chown_cmd = "sudo /bin/chown -R #{@secure_uid}:#{@secure_gid} #{tmp_dir} 2>&1"
chown_output = `#{chown_cmd}`
if $?.exitstatus != 0
@logger.error("Failed chowning install dir: #{chown_output}")
return nil
end
end
package_link = "#{@name}@#{@resolved_version}"
cmd = @npm_helper.install_cmd(package_link, install_dir, npm_cache_dir,
npm_tmp_dir, @secure_uid, @secure_gid)
if @secure_uid
cmd ="sudo -u '##{@secure_uid}' sg #{secure_group} -c \"cd #{tmp_dir} && #{cmd}\" 2>&1"
else
cmd ="cd #{tmp_dir} && #{cmd}"
end
output = nil
IO.popen(cmd) do |io|
output = io.read
end
child_status = $?.exitstatus
if child_status != 0
@logger.warn("Failed installing package: #{@name}")
if output =~ /npm not ok/
output.lines.grep(/^npm ERR! message/) do |error_message|
@logger.warn(error_message.chomp)
end
end
end
if @secure_uid
# Kill any stray processes that the npm compilation may have created
`sudo -u '##{@secure_uid}' pkill -9 -U #{@secure_uid} 2>&1`
me = `whoami`.chomp
`sudo chown -R #{me} #{tmp_dir}`
@logger.debug("Failed chowning #{tmp_dir} to #{me}") if $?.exitstatus != 0
end
package_dir = File.join(install_dir, "node_modules", @name)
return package_dir if child_status == 0
end
def resolved_version_data
package_link = "#{@name}@\"#{@version}\""
output = `#{@npm_helper.versioner_cmd(package_link)} 2>&1`
if $?.exitstatus != 0 || output.empty?
return nil
else
begin
resolved = Yajl::Parser.parse(output)
rescue Exception=>e
return nil
end
end
return resolved
end
private
def url_provided?
@version =~ /^http/ or @version =~ /^git/
end
def secure_group
group_name = `awk -F: '{ if ( $3 == #{@secure_gid} ) { print $1 } }' /etc/group`
group_name.chomp
end
end

Просмотреть файл

@ -0,0 +1,63 @@
require "logger"
require "fileutils"
require File.expand_path('../npm_cache', __FILE__)
require File.expand_path('../npm_package', __FILE__)
require File.expand_path('../npm_helper', __FILE__)
module NpmSupport
# If there is no dependencies config in package.json don't do anything
# For each dependency:
# - Resolve its version (Fail if not possible)
# - Get from cache by name & version
# - If not in cache, run npm install, put in cache
def compile_node_modules
# npm install support only if dependencies provided in package.json
@dependencies = get_dependencies
return unless @dependencies.is_a?(Hash)
# npm provided?
return nil unless runtime["npm"]
@npm_helper = NpmHelper.new(runtime["executable"], runtime["version"], runtime["npm"])
return unless @npm_helper.npm_version
@app_dir = File.expand_path(File.join(destination_directory, "app"))
@app_modules_dir = File.join(@app_dir, "node_modules")
setup_logger
cache_base_dir = StagingPlugin.platform_config["cache"]
cache_dir = File.join(cache_base_dir, "node_modules", library_version)
@cache = NpmCache.new(cache_dir, @logger)
install_packages
end
def install_packages
@logger.info("Installing dependencies. Node version #{runtime["version"]}")
@dependencies.each do |name, version|
package = NpmPackage.new(name, version, @app_modules_dir, @staging_uid,
@staging_gid, @npm_helper, @logger, @cache)
package.install
end
end
def get_dependencies
@package_config["dependencies"] if @package_config.is_a?(Hash)
end
def library_version
environment[:runtime] == "node06" ? "06" : "04"
end
def setup_logger
log_file = File.expand_path(File.join(@app_dir, "..", "logs", "staging.log"))
FileUtils.mkdir_p(File.dirname(log_file))
@logger = Logger.new(log_file)
@logger.level = ENV["DEBUG"] ? Logger::DEBUG : Logger::INFO
@logger.formatter = lambda { |sev, time, pname, msg| "#{msg}\n" }
end
end

Просмотреть файл

@ -1,4 +1,8 @@
require File.expand_path('../npm_support/npm_support', __FILE__)
class NodePlugin < StagingPlugin
include NpmSupport
# TODO - Is there a way to avoid this without some kind of 'register' callback?
# e.g. StagingPlugin.register('sinatra', __FILE__)
def framework
@ -9,6 +13,8 @@ class NodePlugin < StagingPlugin
Dir.chdir(destination_directory) do
create_app_directories
copy_source_files
read_configs
compile_node_modules
create_startup_script
create_stop_script
end
@ -32,14 +38,19 @@ class NodePlugin < StagingPlugin
generate_stop_script(vars)
end
# detect start script from package.json
def package_json_start
def read_configs
package = File.join(destination_directory, 'app', 'package.json')
if File.exists? package
json = Yajl::Parser.parse(File.new(package, 'r'))
if scripts = json["scripts"] and start = scripts["start"]
start.sub(/^\s*node\s+/, "")
end
@package_config = Yajl::Parser.parse(File.new(package, 'r'))
end
end
# detect start script from package.json
def package_json_start
if @package_config.is_a?(Hash) &&
@package_config["scripts"].is_a?(Hash) &&
@package_config["scripts"]["start"]
@package_config["scripts"]["start"].sub(/^\s*node\s+/, "")
end
end

23
staging/lib/vcap/staging/plugin/node/resources/versioner/node_modules/semver/LICENSE сгенерированный поставляемый Normal file
Просмотреть файл

@ -0,0 +1,23 @@
Copyright 2009, 2010, 2011 Isaac Z. Schlueter.
All rights reserved.
Permission is hereby granted, free of charge, to any person
obtaining a copy of this software and associated documentation
files (the "Software"), to deal in the Software without
restriction, including without limitation the rights to use,
copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following
conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
OTHER DEALINGS IN THE SOFTWARE.

119
staging/lib/vcap/staging/plugin/node/resources/versioner/node_modules/semver/README.md сгенерированный поставляемый Normal file
Просмотреть файл

@ -0,0 +1,119 @@
semver(1) -- The semantic versioner for npm
===========================================
## Usage
$ npm install semver
semver.valid('1.2.3') // true
semver.valid('a.b.c') // false
semver.clean(' =v1.2.3 ') // '1.2.3'
semver.satisfies('1.2.3', '1.x || >=2.5.0 || 5.0.0 - 7.2.3') // true
semver.gt('1.2.3', '9.8.7') // false
semver.lt('1.2.3', '9.8.7') // true
As a command-line utility:
$ semver -h
Usage: semver -v <version> [-r <range>]
Test if version(s) satisfy the supplied range(s),
and sort them.
Multiple versions or ranges may be supplied.
Program exits successfully if any valid version satisfies
all supplied ranges, and prints all satisfying versions.
If no versions are valid, or ranges are not satisfied,
then exits failure.
Versions are printed in ascending order, so supplying
multiple versions to the utility will just sort them.
## Versions
A version is the following things, in this order:
* a number (Major)
* a period
* a number (minor)
* a period
* a number (patch)
* OPTIONAL: a hyphen, followed by a number (build)
* OPTIONAL: a collection of pretty much any non-whitespace characters
(tag)
A leading `"="` or `"v"` character is stripped off and ignored.
## Comparisons
The ordering of versions is done using the following algorithm, given
two versions and asked to find the greater of the two:
* If the majors are numerically different, then take the one
with a bigger major number. `2.3.4 > 1.3.4`
* If the minors are numerically different, then take the one
with the bigger minor number. `2.3.4 > 2.2.4`
* If the patches are numerically different, then take the one with the
bigger patch number. `2.3.4 > 2.3.3`
* If only one of them has a build number, then take the one with the
build number. `2.3.4-0 > 2.3.4`
* If they both have build numbers, and the build numbers are numerically
different, then take the one with the bigger build number.
`2.3.4-10 > 2.3.4-9`
* If only one of them has a tag, then take the one without the tag.
`2.3.4 > 2.3.4-beta`
* If they both have tags, then take the one with the lexicographically
larger tag. `2.3.4-beta > 2.3.4-alpha`
* At this point, they're equal.
## Ranges
The following range styles are supported:
* `>1.2.3` Greater than a specific version.
* `<1.2.3` Less than
* `1.2.3 - 2.3.4` := `>=1.2.3 <=2.3.4`
* `~1.2.3` := `>=1.2.3 <1.3.0`
* `~1.2` := `>=1.2.0 <2.0.0`
* `~1` := `>=1.0.0 <2.0.0`
* `1.2.x` := `>=1.2.0 <1.3.0`
* `1.x` := `>=1.0.0 <2.0.0`
Ranges can be joined with either a space (which implies "and") or a
`||` (which implies "or").
## Functions
* valid(v): Return the parsed version, or null if it's not valid.
* inc(v, release): Return the version incremented by the release type
(major, minor, patch, or build), or null if it's not valid.
### Comparison
* gt(v1, v2): `v1 > v2`
* gte(v1, v2): `v1 >= v2`
* lt(v1, v2): `v1 < v2`
* lte(v1, v2): `v1 <= v2`
* eq(v1, v2): `v1 == v2` This is true if they're logically equivalent,
even if they're not the exact same string. You already know how to
compare strings.
* neq(v1, v2): `v1 != v2` The opposite of eq.
* cmp(v1, comparator, v2): Pass in a comparison string, and it'll call
the corresponding function above. `"==="` and `"!=="` do simple
string comparison, but are included for completeness. Throws if an
invalid comparison string is provided.
* compare(v1, v2): Return 0 if v1 == v2, or 1 if v1 is greater, or -1 if
v2 is greater. Sorts in ascending order if passed to Array.sort().
* rcompare(v1, v2): The reverse of compare. Sorts an array of versions
in descending order when passed to Array.sort().
### Ranges
* validRange(range): Return the valid range or null if it's not valid
* satisfies(version, range): Return true if the version satisfies the
range.
* maxSatisfying(versions, range): Return the highest version in the list
that satisfies the range, or null if none of them do.

69
staging/lib/vcap/staging/plugin/node/resources/versioner/node_modules/semver/bin/semver сгенерированный поставляемый Executable file
Просмотреть файл

@ -0,0 +1,69 @@
#!/usr/bin/env node
// Standalone semver comparison program.
// Exits successfully and prints matching version(s) if
// any supplied version is valid and passes all tests.
var argv = process.argv.slice(2)
, versions = []
, range = []
, gt = []
, lt = []
, eq = []
, semver = require("../semver")
main()
function main () {
if (!argv.length) return help()
while (argv.length) {
var a
switch (a = argv.shift()) {
case "-v": case "--version":
versions.push(argv.shift())
break
case "-r": case "--range":
range.push(argv.shift())
break
case "-h": case "--help": case "-?":
return help()
default:
versions.push(a)
break
}
}
versions = versions.filter(semver.valid)
for (var i = 0, l = range.length; i < l ; i ++) {
versions = versions.filter(function (v) {
return semver.satisfies(v, range[i])
})
if (!versions.length) return fail()
}
return success(versions)
}
function fail () { process.exit(1) }
function success () {
versions.sort(semver.compare)
.map(semver.clean)
.forEach(function (v,i,_) { console.log(v) })
}
function help () {
console.log(["Usage: semver -v <version> [-r <range>]"
,"Test if version(s) satisfy the supplied range(s),"
,"and sort them."
,""
,"Multiple versions or ranges may be supplied."
,""
,"Program exits successfully if any valid version satisfies"
,"all supplied ranges, and prints all satisfying versions."
,""
,"If no versions are valid, or ranges are not satisfied,"
,"then exits failure."
,""
,"Versions are printed in ascending order, so supplying"
,"multiple versions to the utility will just sort them."
].join("\n"))
}

34
staging/lib/vcap/staging/plugin/node/resources/versioner/node_modules/semver/package.json сгенерированный поставляемый Normal file
Просмотреть файл

@ -0,0 +1,34 @@
{
"name": "semver",
"version": "1.0.13",
"description": "The semantic version parser used by npm.",
"main": "semver.js",
"scripts": {
"test": "tap test.js"
},
"devDependencies": {
"tap": "0.x >=0.0.4"
},
"license": {
"type": "MIT",
"url": "https://github.com/isaacs/semver/raw/master/LICENSE"
},
"repository": {
"type": "git",
"url": "git://github.com/isaacs/node-semver.git"
},
"bin": {
"semver": "./bin/semver"
},
"_id": "semver@1.0.13",
"dependencies": {},
"optionalDependencies": {},
"engines": {
"node": "*"
},
"_engineSupported": true,
"_npmVersion": "1.1.9",
"_nodeVersion": "v0.6.12",
"_defaultsLoaded": true,
"_from": "semver@"
}

305
staging/lib/vcap/staging/plugin/node/resources/versioner/node_modules/semver/semver.js сгенерированный поставляемый Normal file
Просмотреть файл

@ -0,0 +1,305 @@
;(function (exports) { // nothing in here is node-specific.
// See http://semver.org/
// This implementation is a *hair* less strict in that it allows
// v1.2.3 things, and also tags that don't begin with a char.
var semver = "\\s*[v=]*\\s*([0-9]+)" // major
+ "\\.([0-9]+)" // minor
+ "\\.([0-9]+)" // patch
+ "(-[0-9]+-?)?" // build
+ "([a-zA-Z-][a-zA-Z0-9-\.:]*)?" // tag
, exprComparator = "^((<|>)?=?)\s*("+semver+")$|^$"
, xRangePlain = "[v=]*([0-9]+|x|X|\\*)"
+ "(?:\\.([0-9]+|x|X|\\*)"
+ "(?:\\.([0-9]+|x|X|\\*)"
+ "([a-zA-Z-][a-zA-Z0-9-\.:]*)?)?)?"
, xRange = "((?:<|>)?=?)?\\s*" + xRangePlain
, exprSpermy = "(?:~>?)"+xRange
, expressions = exports.expressions =
{ parse : new RegExp("^\\s*"+semver+"\\s*$")
, parsePackage : new RegExp("^\\s*([^\/]+)[-@](" +semver+")\\s*$")
, parseRange : new RegExp(
"^\\s*(" + semver + ")\\s+-\\s+(" + semver + ")\\s*$")
, validComparator : new RegExp("^"+exprComparator+"$")
, parseXRange : new RegExp("^"+xRange+"$")
, parseSpermy : new RegExp("^"+exprSpermy+"$")
}
Object.getOwnPropertyNames(expressions).forEach(function (i) {
exports[i] = function (str) {
return ("" + (str || "")).match(expressions[i])
}
})
exports.rangeReplace = ">=$1 <=$7"
exports.clean = clean
exports.compare = compare
exports.rcompare = rcompare
exports.satisfies = satisfies
exports.gt = gt
exports.gte = gte
exports.lt = lt
exports.lte = lte
exports.eq = eq
exports.neq = neq
exports.cmp = cmp
exports.inc = inc
exports.valid = valid
exports.validPackage = validPackage
exports.validRange = validRange
exports.maxSatisfying = maxSatisfying
exports.replaceStars = replaceStars
exports.toComparators = toComparators
function stringify (version) {
var v = version
return [v[1]||'', v[2]||'', v[3]||''].join(".") + (v[4]||'') + (v[5]||'')
}
function clean (version) {
version = exports.parse(version)
if (!version) return version
return stringify(version)
}
function valid (version) {
if (typeof version !== "string") return null
return exports.parse(version) && version.trim().replace(/^[v=]+/, '')
}
function validPackage (version) {
if (typeof version !== "string") return null
return version.match(expressions.parsePackage) && version.trim()
}
// range can be one of:
// "1.0.3 - 2.0.0" range, inclusive, like ">=1.0.3 <=2.0.0"
// ">1.0.2" like 1.0.3 - 9999.9999.9999
// ">=1.0.2" like 1.0.2 - 9999.9999.9999
// "<2.0.0" like 0.0.0 - 1.9999.9999
// ">1.0.2 <2.0.0" like 1.0.3 - 1.9999.9999
var starExpression = /(<|>)?=?\s*\*/g
, starReplace = ""
, compTrimExpression = new RegExp("((<|>)?=?)\\s*("
+semver+"|"+xRangePlain+")", "g")
, compTrimReplace = "$1$3"
function toComparators (range) {
var ret = (range || "").trim()
.replace(expressions.parseRange, exports.rangeReplace)
.replace(compTrimExpression, compTrimReplace)
.split(/\s+/)
.join(" ")
.split("||")
.map(function (orchunk) {
return orchunk
.split(" ")
.map(replaceXRanges)
.map(replaceSpermies)
.map(replaceStars)
.join(" ").trim()
})
.map(function (orchunk) {
return orchunk
.trim()
.split(/\s+/)
.filter(function (c) { return c.match(expressions.validComparator) })
})
.filter(function (c) { return c.length })
return ret
}
function replaceStars (stars) {
return stars.trim().replace(starExpression, starReplace)
}
// "2.x","2.x.x" --> ">=2.0.0- <2.1.0-"
// "2.3.x" --> ">=2.3.0- <2.4.0-"
function replaceXRanges (ranges) {
return ranges.split(/\s+/)
.map(replaceXRange)
.join(" ")
}
function replaceXRange (version) {
return version.trim().replace(expressions.parseXRange,
function (v, gtlt, M, m, p, t) {
var anyX = !M || M.toLowerCase() === "x" || M === "*"
|| !m || m.toLowerCase() === "x" || m === "*"
|| !p || p.toLowerCase() === "x" || p === "*"
, ret = v
if (gtlt && anyX) {
// just replace x'es with zeroes
;(!M || M === "*" || M.toLowerCase() === "x") && (M = 0)
;(!m || m === "*" || m.toLowerCase() === "x") && (m = 0)
;(!p || p === "*" || p.toLowerCase() === "x") && (p = 0)
ret = gtlt + M+"."+m+"."+p+"-"
} else if (!M || M === "*" || M.toLowerCase() === "x") {
ret = "*" // allow any
} else if (!m || m === "*" || m.toLowerCase() === "x") {
// append "-" onto the version, otherwise
// "1.x.x" matches "2.0.0beta", since the tag
// *lowers* the version value
ret = ">="+M+".0.0- <"+(+M+1)+".0.0-"
} else if (!p || p === "*" || p.toLowerCase() === "x") {
ret = ">="+M+"."+m+".0- <"+M+"."+(+m+1)+".0-"
}
//console.error("parseXRange", [].slice.call(arguments), ret)
return ret
})
}
// ~, ~> --> * (any, kinda silly)
// ~2, ~2.x, ~2.x.x, ~>2, ~>2.x ~>2.x.x --> >=2.0.0 <3.0.0
// ~2.0, ~2.0.x, ~>2.0, ~>2.0.x --> >=2.0.0 <2.1.0
// ~1.2, ~1.2.x, ~>1.2, ~>1.2.x --> >=1.2.0 <1.3.0
// ~1.2.3, ~>1.2.3 --> >=1.2.3 <1.3.0
// ~1.2.0, ~>1.2.0 --> >=1.2.0 <1.3.0
function replaceSpermies (version) {
return version.trim().replace(expressions.parseSpermy,
function (v, gtlt, M, m, p, t) {
if (gtlt) throw new Error(
"Using '"+gtlt+"' with ~ makes no sense. Don't do it.")
if (!M || M.toLowerCase() === "x") {
return ""
}
// ~1 == >=1.0.0- <2.0.0-
if (!m || m.toLowerCase() === "x") {
return ">="+M+".0.0- <"+(+M+1)+".0.0-"
}
// ~1.2 == >=1.2.0- <1.3.0-
if (!p || p.toLowerCase() === "x") {
return ">="+M+"."+m+".0- <"+M+"."+(+m+1)+".0-"
}
// ~1.2.3 == >=1.2.3- <1.3.0-
t = t || "-"
return ">="+M+"."+m+"."+p+t+" <"+M+"."+(+m+1)+".0-"
})
}
function validRange (range) {
range = replaceStars(range)
var c = toComparators(range)
return (c.length === 0)
? null
: c.map(function (c) { return c.join(" ") }).join("||")
}
// returns the highest satisfying version in the list, or undefined
function maxSatisfying (versions, range) {
return versions
.filter(function (v) { return satisfies(v, range) })
.sort(compare)
.pop()
}
function satisfies (version, range) {
version = valid(version)
if (!version) return false
range = toComparators(range)
for (var i = 0, l = range.length ; i < l ; i ++) {
var ok = false
for (var j = 0, ll = range[i].length ; j < ll ; j ++) {
var r = range[i][j]
, gtlt = r.charAt(0) === ">" ? gt
: r.charAt(0) === "<" ? lt
: false
, eq = r.charAt(!!gtlt) === "="
, sub = (!!eq) + (!!gtlt)
if (!gtlt) eq = true
r = r.substr(sub)
r = (r === "") ? r : valid(r)
ok = (r === "") || (eq && r === version) || (gtlt && gtlt(version, r))
if (!ok) break
}
if (ok) return true
}
return false
}
// return v1 > v2 ? 1 : -1
function compare (v1, v2) {
var g = gt(v1, v2)
return g === null ? 0 : g ? 1 : -1
}
function rcompare (v1, v2) {
return compare(v2, v1)
}
function lt (v1, v2) { return gt(v2, v1) }
function gte (v1, v2) { return !lt(v1, v2) }
function lte (v1, v2) { return !gt(v1, v2) }
function eq (v1, v2) { return gt(v1, v2) === null }
function neq (v1, v2) { return gt(v1, v2) !== null }
function cmp (v1, c, v2) {
switch (c) {
case ">": return gt(v1, v2)
case "<": return lt(v1, v2)
case ">=": return gte(v1, v2)
case "<=": return lte(v1, v2)
case "==": return eq(v1, v2)
case "!=": return neq(v1, v2)
case "===": return v1 === v2
case "!==": return v1 !== v2
default: throw new Error("Y U NO USE VALID COMPARATOR!? "+c)
}
}
// return v1 > v2
function num (v) {
return v === undefined ? -1 : parseInt((v||"0").replace(/[^0-9]+/g, ''), 10)
}
function gt (v1, v2) {
v1 = exports.parse(v1)
v2 = exports.parse(v2)
if (!v1 || !v2) return false
for (var i = 1; i < 5; i ++) {
v1[i] = num(v1[i])
v2[i] = num(v2[i])
if (v1[i] > v2[i]) return true
else if (v1[i] !== v2[i]) return false
}
// no tag is > than any tag, or use lexicographical order.
var tag1 = v1[5] || ""
, tag2 = v2[5] || ""
// kludge: null means they were equal. falsey, and detectable.
// embarrassingly overclever, though, I know.
return tag1 === tag2 ? null
: !tag1 ? true
: !tag2 ? false
: tag1 > tag2
}
function inc (version, release) {
version = exports.parse(version)
if (!version) return null
var parsedIndexLookup =
{ 'major': 1
, 'minor': 2
, 'patch': 3
, 'build': 4 }
var incIndex = parsedIndexLookup[release]
if (incIndex === undefined) return null
var current = num(version[incIndex])
version[incIndex] = current === -1 ? 1 : current + 1
for (var i = incIndex + 1; i < 5; i ++) {
if (num(version[i]) !== -1) version[i] = "0"
}
if (version[4]) version[4] = "-" + version[4]
version[5] = ""
return stringify(version)
}
})(typeof exports === "object" ? exports : semver = {})

397
staging/lib/vcap/staging/plugin/node/resources/versioner/node_modules/semver/test.js сгенерированный поставляемый Normal file
Просмотреть файл

@ -0,0 +1,397 @@
var tap = require("tap")
, test = tap.test
, semver = require("./semver.js")
, eq = semver.eq
, gt = semver.gt
, lt = semver.lt
, neq = semver.neq
, cmp = semver.cmp
, gte = semver.gte
, lte = semver.lte
, satisfies = semver.satisfies
, validRange = semver.validRange
, inc = semver.inc
, replaceStars = semver.replaceStars
, toComparators = semver.toComparators
tap.plan(8)
test("\ncomparison tests", function (t) {
; [ ["0.0.0", "0.0.0foo"]
, ["0.0.1", "0.0.0"]
, ["1.0.0", "0.9.9"]
, ["0.10.0", "0.9.0"]
, ["0.99.0", "0.10.0"]
, ["2.0.0", "1.2.3"]
, ["v0.0.0", "0.0.0foo"]
, ["v0.0.1", "0.0.0"]
, ["v1.0.0", "0.9.9"]
, ["v0.10.0", "0.9.0"]
, ["v0.99.0", "0.10.0"]
, ["v2.0.0", "1.2.3"]
, ["0.0.0", "v0.0.0foo"]
, ["0.0.1", "v0.0.0"]
, ["1.0.0", "v0.9.9"]
, ["0.10.0", "v0.9.0"]
, ["0.99.0", "v0.10.0"]
, ["2.0.0", "v1.2.3"]
, ["1.2.3", "1.2.3-asdf"]
, ["1.2.3-4", "1.2.3"]
, ["1.2.3-4-foo", "1.2.3"]
, ["1.2.3-5", "1.2.3-5-foo"]
, ["1.2.3-5", "1.2.3-4"]
, ["1.2.3-5-foo", "1.2.3-5-Foo"]
].forEach(function (v) {
var v0 = v[0]
, v1 = v[1]
t.ok(gt(v0, v1), "gt('"+v0+"', '"+v1+"')")
t.ok(lt(v1, v0), "lt('"+v1+"', '"+v0+"')")
t.ok(!gt(v1, v0), "!gt('"+v1+"', '"+v0+"')")
t.ok(!lt(v0, v1), "!lt('"+v0+"', '"+v1+"')")
t.ok(eq(v0, v0), "eq('"+v0+"', '"+v0+"')")
t.ok(eq(v1, v1), "eq('"+v1+"', '"+v1+"')")
t.ok(neq(v0, v1), "neq('"+v0+"', '"+v1+"')")
t.ok(cmp(v1, "==", v1), "cmp('"+v1+"' == '"+v1+"')")
t.ok(cmp(v0, ">=", v1), "cmp('"+v0+"' >= '"+v1+"')")
t.ok(cmp(v1, "<=", v0), "cmp('"+v1+"' <= '"+v0+"')")
t.ok(cmp(v0, "!=", v1), "cmp('"+v0+"' != '"+v1+"')")
})
t.end()
})
test("\nequality tests", function (t) {
; [ ["1.2.3", "v1.2.3"]
, ["1.2.3", "=1.2.3"]
, ["1.2.3", "v 1.2.3"]
, ["1.2.3", "= 1.2.3"]
, ["1.2.3", " v1.2.3"]
, ["1.2.3", " =1.2.3"]
, ["1.2.3", " v 1.2.3"]
, ["1.2.3", " = 1.2.3"]
, ["1.2.3-0", "v1.2.3-0"]
, ["1.2.3-0", "=1.2.3-0"]
, ["1.2.3-0", "v 1.2.3-0"]
, ["1.2.3-0", "= 1.2.3-0"]
, ["1.2.3-0", " v1.2.3-0"]
, ["1.2.3-0", " =1.2.3-0"]
, ["1.2.3-0", " v 1.2.3-0"]
, ["1.2.3-0", " = 1.2.3-0"]
, ["1.2.3-01", "v1.2.3-1"]
, ["1.2.3-01", "=1.2.3-1"]
, ["1.2.3-01", "v 1.2.3-1"]
, ["1.2.3-01", "= 1.2.3-1"]
, ["1.2.3-01", " v1.2.3-1"]
, ["1.2.3-01", " =1.2.3-1"]
, ["1.2.3-01", " v 1.2.3-1"]
, ["1.2.3-01", " = 1.2.3-1"]
, ["1.2.3beta", "v1.2.3beta"]
, ["1.2.3beta", "=1.2.3beta"]
, ["1.2.3beta", "v 1.2.3beta"]
, ["1.2.3beta", "= 1.2.3beta"]
, ["1.2.3beta", " v1.2.3beta"]
, ["1.2.3beta", " =1.2.3beta"]
, ["1.2.3beta", " v 1.2.3beta"]
, ["1.2.3beta", " = 1.2.3beta"]
].forEach(function (v) {
var v0 = v[0]
, v1 = v[1]
t.ok(eq(v0, v1), "eq('"+v0+"', '"+v1+"')")
t.ok(!neq(v0, v1), "!neq('"+v0+"', '"+v1+"')")
t.ok(cmp(v0, "==", v1), "cmp("+v0+"=="+v1+")")
t.ok(!cmp(v0, "!=", v1), "!cmp("+v0+"!="+v1+")")
t.ok(!cmp(v0, "===", v1), "!cmp("+v0+"==="+v1+")")
t.ok(cmp(v0, "!==", v1), "cmp("+v0+"!=="+v1+")")
t.ok(!gt(v0, v1), "!gt('"+v0+"', '"+v1+"')")
t.ok(gte(v0, v1), "gte('"+v0+"', '"+v1+"')")
t.ok(!lt(v0, v1), "!lt('"+v0+"', '"+v1+"')")
t.ok(lte(v0, v1), "lte('"+v0+"', '"+v1+"')")
})
t.end()
})
test("\nrange tests", function (t) {
; [ ["1.0.0 - 2.0.0", "1.2.3"]
, ["1.0.0", "1.0.0"]
, [">=*", "0.2.4"]
, ["", "1.0.0"]
, ["*", "1.2.3"]
, ["*", "v1.2.3-foo"]
, [">=1.0.0", "1.0.0"]
, [">=1.0.0", "1.0.1"]
, [">=1.0.0", "1.1.0"]
, [">1.0.0", "1.0.1"]
, [">1.0.0", "1.1.0"]
, ["<=2.0.0", "2.0.0"]
, ["<=2.0.0", "1.9999.9999"]
, ["<=2.0.0", "0.2.9"]
, ["<2.0.0", "1.9999.9999"]
, ["<2.0.0", "0.2.9"]
, [">= 1.0.0", "1.0.0"]
, [">= 1.0.0", "1.0.1"]
, [">= 1.0.0", "1.1.0"]
, ["> 1.0.0", "1.0.1"]
, ["> 1.0.0", "1.1.0"]
, ["<= 2.0.0", "2.0.0"]
, ["<= 2.0.0", "1.9999.9999"]
, ["<= 2.0.0", "0.2.9"]
, ["< 2.0.0", "1.9999.9999"]
, ["<\t2.0.0", "0.2.9"]
, [">=0.1.97", "v0.1.97"]
, [">=0.1.97", "0.1.97"]
, ["0.1.20 || 1.2.4", "1.2.4"]
, [">=0.2.3 || <0.0.1", "0.0.0"]
, [">=0.2.3 || <0.0.1", "0.2.3"]
, [">=0.2.3 || <0.0.1", "0.2.4"]
, ["||", "1.3.4"]
, ["2.x.x", "2.1.3"]
, ["1.2.x", "1.2.3"]
, ["1.2.x || 2.x", "2.1.3"]
, ["1.2.x || 2.x", "1.2.3"]
, ["x", "1.2.3"]
, ["2.*.*", "2.1.3"]
, ["1.2.*", "1.2.3"]
, ["1.2.* || 2.*", "2.1.3"]
, ["1.2.* || 2.*", "1.2.3"]
, ["*", "1.2.3"]
, ["2", "2.1.2"]
, ["2.3", "2.3.1"]
, ["~2.4", "2.4.0"] // >=2.4.0 <2.5.0
, ["~2.4", "2.4.5"]
, ["~>3.2.1", "3.2.2"] // >=3.2.1 <3.3.0
, ["~1", "1.2.3"] // >=1.0.0 <2.0.0
, ["~>1", "1.2.3"]
, ["~> 1", "1.2.3"]
, ["~1.0", "1.0.2"] // >=1.0.0 <1.1.0
, ["~ 1.0", "1.0.2"]
, [">=1", "1.0.0"]
, [">= 1", "1.0.0"]
, ["<1.2", "1.1.1"]
, ["< 1.2", "1.1.1"]
, ["1", "1.0.0beta"]
, ["~v0.5.4-pre", "0.5.5"]
, ["~v0.5.4-pre", "0.5.4"]
].forEach(function (v) {
t.ok(satisfies(v[1], v[0]), v[0]+" satisfied by "+v[1])
})
t.end()
})
test("\nnegative range tests", function (t) {
; [ ["1.0.0 - 2.0.0", "2.2.3"]
, ["1.0.0", "1.0.1"]
, [">=1.0.0", "0.0.0"]
, [">=1.0.0", "0.0.1"]
, [">=1.0.0", "0.1.0"]
, [">1.0.0", "0.0.1"]
, [">1.0.0", "0.1.0"]
, ["<=2.0.0", "3.0.0"]
, ["<=2.0.0", "2.9999.9999"]
, ["<=2.0.0", "2.2.9"]
, ["<2.0.0", "2.9999.9999"]
, ["<2.0.0", "2.2.9"]
, [">=0.1.97", "v0.1.93"]
, [">=0.1.97", "0.1.93"]
, ["0.1.20 || 1.2.4", "1.2.3"]
, [">=0.2.3 || <0.0.1", "0.0.3"]
, [">=0.2.3 || <0.0.1", "0.2.2"]
, ["2.x.x", "1.1.3"]
, ["2.x.x", "3.1.3"]
, ["1.2.x", "1.3.3"]
, ["1.2.x || 2.x", "3.1.3"]
, ["1.2.x || 2.x", "1.1.3"]
, ["2.*.*", "1.1.3"]
, ["2.*.*", "3.1.3"]
, ["1.2.*", "1.3.3"]
, ["1.2.* || 2.*", "3.1.3"]
, ["1.2.* || 2.*", "1.1.3"]
, ["2", "1.1.2"]
, ["2.3", "2.4.1"]
, ["~2.4", "2.5.0"] // >=2.4.0 <2.5.0
, ["~2.4", "2.3.9"]
, ["~>3.2.1", "3.3.2"] // >=3.2.1 <3.3.0
, ["~>3.2.1", "3.2.0"] // >=3.2.1 <3.3.0
, ["~1", "0.2.3"] // >=1.0.0 <2.0.0
, ["~>1", "2.2.3"]
, ["~1.0", "1.1.0"] // >=1.0.0 <1.1.0
, ["<1", "1.0.0"]
, [">=1.2", "1.1.1"]
, ["1", "2.0.0beta"]
, ["~v0.5.4-beta", "0.5.4-alpha"]
, ["<1", "1.0.0beta"]
, ["< 1", "1.0.0beta"]
].forEach(function (v) {
t.ok(!satisfies(v[1], v[0]), v[0]+" not satisfied by "+v[1])
})
t.end()
})
test("\nincrement versions test", function (t) {
; [ [ "1.2.3", "major", "2.0.0" ]
, [ "1.2.3", "minor", "1.3.0" ]
, [ "1.2.3", "patch", "1.2.4" ]
, [ "1.2.3", "build", "1.2.3-1" ]
, [ "1.2.3-4", "build", "1.2.3-5" ]
, [ "1.2.3tag", "major", "2.0.0" ]
, [ "1.2.3-tag", "major", "2.0.0" ]
, [ "1.2.3tag", "build", "1.2.3-1" ]
, [ "1.2.3-tag", "build", "1.2.3-1" ]
, [ "1.2.3-4-tag", "build", "1.2.3-5" ]
, [ "1.2.3-4tag", "build", "1.2.3-5" ]
, [ "1.2.3", "fake", null ]
, [ "fake", "major", null ]
].forEach(function (v) {
t.equal(inc(v[0], v[1]), v[2], "inc("+v[0]+", "+v[1]+") === "+v[2])
})
t.end()
})
test("\nreplace stars test", function (t) {
; [ [ "", "" ]
, [ "*", "" ]
, [ "> *", "" ]
, [ "<*", "" ]
, [ " >= *", "" ]
, [ "* || 1.2.3", " || 1.2.3" ]
].forEach(function (v) {
t.equal(replaceStars(v[0]), v[1], "replaceStars("+v[0]+") === "+v[1])
})
t.end()
})
test("\nvalid range test", function (t) {
; [ ["1.0.0 - 2.0.0", ">=1.0.0 <=2.0.0"]
, ["1.0.0", "1.0.0"]
, [">=*", ""]
, ["", ""]
, ["*", ""]
, ["*", ""]
, [">=1.0.0", ">=1.0.0"]
, [">1.0.0", ">1.0.0"]
, ["<=2.0.0", "<=2.0.0"]
, ["1", ">=1.0.0- <2.0.0-"]
, ["<=2.0.0", "<=2.0.0"]
, ["<=2.0.0", "<=2.0.0"]
, ["<2.0.0", "<2.0.0"]
, ["<2.0.0", "<2.0.0"]
, [">= 1.0.0", ">=1.0.0"]
, [">= 1.0.0", ">=1.0.0"]
, [">= 1.0.0", ">=1.0.0"]
, ["> 1.0.0", ">1.0.0"]
, ["> 1.0.0", ">1.0.0"]
, ["<= 2.0.0", "<=2.0.0"]
, ["<= 2.0.0", "<=2.0.0"]
, ["<= 2.0.0", "<=2.0.0"]
, ["< 2.0.0", "<2.0.0"]
, ["< 2.0.0", "<2.0.0"]
, [">=0.1.97", ">=0.1.97"]
, [">=0.1.97", ">=0.1.97"]
, ["0.1.20 || 1.2.4", "0.1.20||1.2.4"]
, [">=0.2.3 || <0.0.1", ">=0.2.3||<0.0.1"]
, [">=0.2.3 || <0.0.1", ">=0.2.3||<0.0.1"]
, [">=0.2.3 || <0.0.1", ">=0.2.3||<0.0.1"]
, ["||", "||"]
, ["2.x.x", ">=2.0.0- <3.0.0-"]
, ["1.2.x", ">=1.2.0- <1.3.0-"]
, ["1.2.x || 2.x", ">=1.2.0- <1.3.0-||>=2.0.0- <3.0.0-"]
, ["1.2.x || 2.x", ">=1.2.0- <1.3.0-||>=2.0.0- <3.0.0-"]
, ["x", ""]
, ["2.*.*", null]
, ["1.2.*", null]
, ["1.2.* || 2.*", null]
, ["1.2.* || 2.*", null]
, ["*", ""]
, ["2", ">=2.0.0- <3.0.0-"]
, ["2.3", ">=2.3.0- <2.4.0-"]
, ["~2.4", ">=2.4.0- <2.5.0-"]
, ["~2.4", ">=2.4.0- <2.5.0-"]
, ["~>3.2.1", ">=3.2.1- <3.3.0-"]
, ["~1", ">=1.0.0- <2.0.0-"]
, ["~>1", ">=1.0.0- <2.0.0-"]
, ["~> 1", ">=1.0.0- <2.0.0-"]
, ["~1.0", ">=1.0.0- <1.1.0-"]
, ["~ 1.0", ">=1.0.0- <1.1.0-"]
, ["<1", "<1.0.0-"]
, ["< 1", "<1.0.0-"]
, [">=1", ">=1.0.0-"]
, [">= 1", ">=1.0.0-"]
, ["<1.2", "<1.2.0-"]
, ["< 1.2", "<1.2.0-"]
, ["1", ">=1.0.0- <2.0.0-"]
].forEach(function (v) {
t.equal(validRange(v[0]), v[1], "validRange("+v[0]+") === "+v[1])
})
t.end()
})
test("\ncomparators test", function (t) {
; [ ["1.0.0 - 2.0.0", [[">=1.0.0", "<=2.0.0"]] ]
, ["1.0.0", [["1.0.0"]] ]
, [">=*", [[">=0.0.0-"]] ]
, ["", [[""]]]
, ["*", [[""]] ]
, ["*", [[""]] ]
, [">=1.0.0", [[">=1.0.0"]] ]
, [">=1.0.0", [[">=1.0.0"]] ]
, [">=1.0.0", [[">=1.0.0"]] ]
, [">1.0.0", [[">1.0.0"]] ]
, [">1.0.0", [[">1.0.0"]] ]
, ["<=2.0.0", [["<=2.0.0"]] ]
, ["1", [[">=1.0.0-", "<2.0.0-"]] ]
, ["<=2.0.0", [["<=2.0.0"]] ]
, ["<=2.0.0", [["<=2.0.0"]] ]
, ["<2.0.0", [["<2.0.0"]] ]
, ["<2.0.0", [["<2.0.0"]] ]
, [">= 1.0.0", [[">=1.0.0"]] ]
, [">= 1.0.0", [[">=1.0.0"]] ]
, [">= 1.0.0", [[">=1.0.0"]] ]
, ["> 1.0.0", [[">1.0.0"]] ]
, ["> 1.0.0", [[">1.0.0"]] ]
, ["<= 2.0.0", [["<=2.0.0"]] ]
, ["<= 2.0.0", [["<=2.0.0"]] ]
, ["<= 2.0.0", [["<=2.0.0"]] ]
, ["< 2.0.0", [["<2.0.0"]] ]
, ["<\t2.0.0", [["<2.0.0"]] ]
, [">=0.1.97", [[">=0.1.97"]] ]
, [">=0.1.97", [[">=0.1.97"]] ]
, ["0.1.20 || 1.2.4", [["0.1.20"], ["1.2.4"]] ]
, [">=0.2.3 || <0.0.1", [[">=0.2.3"], ["<0.0.1"]] ]
, [">=0.2.3 || <0.0.1", [[">=0.2.3"], ["<0.0.1"]] ]
, [">=0.2.3 || <0.0.1", [[">=0.2.3"], ["<0.0.1"]] ]
, ["||", [[""], [""]] ]
, ["2.x.x", [[">=2.0.0-", "<3.0.0-"]] ]
, ["1.2.x", [[">=1.2.0-", "<1.3.0-"]] ]
, ["1.2.x || 2.x", [[">=1.2.0-", "<1.3.0-"], [">=2.0.0-", "<3.0.0-"]] ]
, ["1.2.x || 2.x", [[">=1.2.0-", "<1.3.0-"], [">=2.0.0-", "<3.0.0-"]] ]
, ["x", [[""]] ]
, ["2.*.*", [[">=2.0.0-", "<3.0.0-"]] ]
, ["1.2.*", [[">=1.2.0-", "<1.3.0-"]] ]
, ["1.2.* || 2.*", [[">=1.2.0-", "<1.3.0-"], [">=2.0.0-", "<3.0.0-"]] ]
, ["1.2.* || 2.*", [[">=1.2.0-", "<1.3.0-"], [">=2.0.0-", "<3.0.0-"]] ]
, ["*", [[""]] ]
, ["2", [[">=2.0.0-", "<3.0.0-"]] ]
, ["2.3", [[">=2.3.0-", "<2.4.0-"]] ]
, ["~2.4", [[">=2.4.0-", "<2.5.0-"]] ]
, ["~2.4", [[">=2.4.0-", "<2.5.0-"]] ]
, ["~>3.2.1", [[">=3.2.1-", "<3.3.0-"]] ]
, ["~1", [[">=1.0.0-", "<2.0.0-"]] ]
, ["~>1", [[">=1.0.0-", "<2.0.0-"]] ]
, ["~> 1", [[">=1.0.0-", "<2.0.0-"]] ]
, ["~1.0", [[">=1.0.0-", "<1.1.0-"]] ]
, ["~ 1.0", [[">=1.0.0-", "<1.1.0-"]] ]
, ["<1", [["<1.0.0-"]] ]
, ["< 1", [["<1.0.0-"]] ]
, [">=1", [[">=1.0.0-"]] ]
, [">= 1", [[">=1.0.0-"]] ]
, ["<1.2", [["<1.2.0-"]] ]
, ["< 1.2", [["<1.2.0-"]] ]
, ["1", [[">=1.0.0-", "<2.0.0-"]] ]
].forEach(function (v) {
t.equivalent(toComparators(v[0]), v[1], "toComparators("+v[0]+") === "+JSON.stringify(v[1]))
})
t.end()
})

Просмотреть файл

@ -0,0 +1,11 @@
{
"name" : "versioner",
"version" : "0.0.1",
"description" : "Version resolver for npm packages",
"engines" : { "node" : ">=0.4" },
"scripts" : "./versioner.js",
"dependencies" : {
"semver" : ""
},
"private" : true
}

Просмотреть файл

@ -0,0 +1,140 @@
;(function () {
module.exports = versioner
versioner.usage = "node versioner.js --package=pkg[@version] [--node-version=version] [--npm-version=version]"
var parsePkg = new RegExp("^--package=(.*)$")
, parseNodeV = new RegExp("^--node-version=(.*)$")
, parseNpmV = new RegExp("^--npm-version=(.*)$")
, nodev = process.version
, pkg = null
, npmv = null
process.argv.forEach(function (arg) {
if (opt = arg.match(parsePkg))
pkg = opt[1]
else if (opt = arg.match(parseNodeV))
nodev = opt[1]
else if (opt = arg.match(parseNpmV))
npmv = opt[1]
});
if (pkg === null || pkg == "") failProcess("Usage: "+versioner.usage+"\n")
var semver = require("semver")
, http = require("http")
, registryUrl = "registry.npmjs.org"
versioner(pkg, nodev, npmv)
function versioner (pkg, nodev, npmv) {
var nv = pkg.split("@")
, name = nv.shift()
, version = nv.join("@") || ""
registryGet(name, null, 10, function (data) {
if (data && typeof data === "string") {
try {
data = JSON.parse(data)
} catch (ex) {
failProcess("Error parsing json from registry")
}
}
else
failProcess("Could not find requested package")
var results = {}
, versions = data.versions
delete data.readme
Object.keys(versions).forEach(function (v) {
var eng = versions[v].engines
if ((semver.satisfies(v, version)) &&
(!eng || (!eng.node || semver.satisfies(nodev, eng.node) &&
(!npmv || !eng.npm || semver.satisfies(npmv, eng.npm))))) {
results[v] = versions[v].dist.tarball
}
})
if (!Object.keys(results).length)
failProcess("No compatible version found")
var sorted = Object.keys(results).sort(semver.compare)
var latestv = sorted.pop()
var result = { "version" : latestv, "source" : results[latestv] }
process.stdout.write(JSON.stringify(result))
})
}
function registryGet (project, version, timeout, cb) {
var uri = []
uri.push(project || "")
if (version) uri.push(version)
uri = uri.join("/")
var options = {
host: registryUrl,
method: "GET",
port: 80,
path: "/"+uri,
headers: { "accept": "application/json" }
}
var request = http.request(options)
, responded = false
request.on("error", function (e) {
failProcess("Error requesting registry: "+e)
})
if (typeof request.setTimeout !== "undefined") {
// >= node 06
request.setTimeout(timeout * 1000, function() {
if (!responded)
request.abort()
})
}
else {
// node 04
process.nextTick(function() {
if (typeof request.connection !== "undefined") {
request.connection.setTimeout(timeout * 1000, function() {
if (!responded) {
request.abort()
failProcess("Connection timeout to npm registry")
}
})
}
})
}
request.on("response", function (res) {
responded = true
if (res.statusCode == "200") {
var body = ""
res.on("data", function (chunk) {
body += chunk
})
res.on("end", function () {
cb(body)
})
}
else
failProcess("Unexpected response from registry: "+res.statusCode)
})
request.end()
}
function failProcess (err) {
process.stdout.write(err)
process.exit(1)
}
})()

Просмотреть файл

@ -1,5 +1,5 @@
module VCAP
module Staging
VERSION = '0.1.50'
VERSION = '0.1.51'
end
end

11
staging/spec/fixtures/apps/node_dependencies/source/app.js поставляемый Normal file
Просмотреть файл

@ -0,0 +1,11 @@
var app = require('express').createServer();
app.get('/', function(req, res){
res.send('hello world test using express and npm. My address:' + app.address().address + ", my port: " + app.address().port);
});
var port = process.env.VCAP_APP_PORT || 3000
app.listen(port);
console.log(app.address());
console.log('Express server started on port %s', app.address().port);

Просмотреть файл

@ -0,0 +1,5 @@
{
"dependencies" : {
"express" : "2.5.x"
}
}

Просмотреть файл

@ -0,0 +1,10 @@
var bcrypt = require("bcrypt"),
host = process.env.VCAP_APP_HOST || 'localhost',
port = process.env.VCAP_APP_PORT || 3000;
require('http').createServer(function (req, res) {
res.writeHead(200, {'Content-Type': 'text/html'});
res.end('Hello from Cloud!');
}).listen(port);
console.log('Server running at http://' + host + ':' + port + '/');

9
staging/spec/fixtures/apps/node_native_dependencies/source/node_modules/bcrypt/CHANGELOG сгенерированный поставляемый Executable file
Просмотреть файл

@ -0,0 +1,9 @@
v0.2.0
* Added async functionality
* API changes
* hashpw -> encrypt
* all old sync methods now end with _sync
* Removed libbsd(arc4random) dependency...now uses openssl which is more widely spread
v0.1.2
* Security fix. Wasn't reading rounds in properly and was always only using 4 rounds.

19
staging/spec/fixtures/apps/node_native_dependencies/source/node_modules/bcrypt/LICENSE сгенерированный поставляемый Executable file
Просмотреть файл

@ -0,0 +1,19 @@
Copyright (c) 2010 Nicholas Campbell
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.

22
staging/spec/fixtures/apps/node_native_dependencies/source/node_modules/bcrypt/Makefile сгенерированный поставляемый Executable file
Просмотреть файл

@ -0,0 +1,22 @@
TESTS = test/*.js
all: test
build: clean configure compile
configure:
node-waf configure
compile:
node-waf build
test: build
@./node_modules/nodeunit/bin/nodeunit \
$(TESTS)
clean:
rm -f bcrypt_lib.node
rm -Rf build
.PHONY: clean test build

174
staging/spec/fixtures/apps/node_native_dependencies/source/node_modules/bcrypt/README.md сгенерированный поставляемый Executable file
Просмотреть файл

@ -0,0 +1,174 @@
node.bcrypt.js
=============
Lib to help you hash passwords.
[bcrypt on wikipedia][bcryptwiki]
Catalyst for this module: [How To Safely Store A Password][codahale]
Security Issues/Concerns
=============
As should be the case with any security tool, this library should be scrutinized by anyone using it. If you find or suspect an issue with the code- please bring it to my attention and I'll spend some time trying to make sure that this tool is as secure as possible.
To make it easier for people using this tool to analyze what has been surveyed, here is a list of BCrypt related security issues/concerns as they've come up.
* An [issue with passwords][jtr] was found with a version of the Blowfish algorithm developed for John the Ripper. This is not present in the OpenBSD version and is thus not a problem for this module. HT [zooko][zooko].
Dependencies
=============
* NodeJS
* OpenSSL
From NPM
============
npm install bcrypt
From Source
============
Assuming you've already built node, you can run the waf script:
node-waf configure
node-waf build
npm link
Usage - Sync
============
To hash a password:
var bcrypt = require('bcrypt');
var salt = bcrypt.gen_salt_sync(10);
var hash = bcrypt.encrypt_sync("B4c0/\/", salt);
// Store hash in your password DB.
To check a password:
// Load hash from your password DB.
bcrypt.compare_sync("B4c0/\/", hash); // true
bcrypt.compare_sync("not_bacon", hash); // false
Usage - Async
============
To hash a password:
var bcrypt = require('bcrypt');
bcrypt.gen_salt(10, function(err, salt) {
bcrypt.encrypt("B4c0/\/", salt, function(err, hash) {
// Store hash in your password DB.
});
});
To check a password:
// Load hash from your password DB.
bcrypt.compare("B4c0/\/", hash, function(err, res) {
// res == true
});
bcrypt.compare("not_bacon", hash, function(err, res) {
// res = false
});
API
============
`BCrypt.`
* `gen_salt_sync(rounds, seed_length)`
* `rounds` - [OPTIONAL] - the number of rounds to process the data for. (default - 10)
* `seed_length` - [OPTIONAL] - RAND_bytes wants a length. to make that a bit flexible, you can specify a seed_length. (default - 20)
* `gen_salt(rounds, seed_length, cb)`
* `rounds` - [OPTIONAL] - the number of rounds to process the data for. (default - 10)
* `seed_length` - [OPTIONAL] - RAND_bytes wants a length. to make that a bit flexible, you can specify a seed_length. (default - 20)
* `cb` - [REQUIRED] - a callback to be fired once the salt has been generated. uses eio making it asynchronous.
* `err` - First parameter to the callback detailing any errors.
* `salt` - Second parameter to the callback providing the generated salt.
* `encrypt_sync(data, salt)`
* `data` - [REQUIRED] - the data to be encrypted.
* `salt` - [REQUIRED] - the salt to be used in encryption.
* `encrypt(data, salt, cb)`
* `data` - [REQUIRED] - the data to be encrypted.
* `salt` - [REQUIRED] - the salt to be used in encryption.
* `cb` - [REQUIRED] - a callback to be fired once the data has been encrypted. uses eio making it asynchronous.
* `err` - First parameter to the callback detailing any errors.
* `encrypted` - Second parameter to the callback providing the encrypted form.
* `compare_sync(data, encrypted)`
* `data` - [REQUIRED] - data to compare.
* `encrypted` - [REQUIRED] - data to be compared to.
* `compare(data, encrypted, cb)`
* `data` - [REQUIRED] - data to compare.
* `encrypted` - [REQUIRED] - data to be compared to.
* `cb` - [REQUIRED] - a callback to be fired once the data has been compared. uses eio making it asynchronous.
* `err` - First parameter to the callback detailing any errors.
* `same` - Second parameter to the callback providing whether the data and encrypted forms match [true | false].
* `get_rounds(encrypted)` - return the number of rounds used to encrypt a given hash
* `encrypted` - [REQUIRED] - hash from which the number of rounds used should be extracted.
Hash Info
============
The characters that comprise the resultant hash are `./ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789$`.
Testing
============
I am using nodeunit. I like the way you write tests with it and I like the default output. As such you'll need it to run the tests. I suspect my tests would run on an older version, but these were written and worked against 0.5.1
npm install nodeunit@0.5.1
nodeunit test/
Credits
============
The code for this comes from a few sources:
* blowfish.cc - OpenBSD
* bcrypt.cc - OpenBSD
* bcrypt::gen_salt - [gen_salt inclusion to bcrypt][bcryptgs]
* bcrypt_node.cc - me
Contributors
============
* [Antonio Salazar Cardozo][shadowfiend] - Early MacOS X support (when we used libbsd)
* [Ben Glow][pixelglow] - Fixes for thread safety with async calls
* [Van Nguyen][thegoleffect] - Found a timing attack in the comparator
* [NewITFarmer][newitfarmer] - Initial Cygwin support
* [David Trejo][dtrejo] - packaging fixes
* [Alfred Westerveld][alfredwesterveld] - packaging fixes
* [Vincent Côté-Roy][vincentr] - Testing around concurrency issues
* [Lloyd Hilaiel][lloyd] - Documentation fixes
* [Roman Shtylman][shtylman] - Code refactoring and general rot reduction
* [Vadim Graboys][vadimg] - Code changes to support 0.5.5+
License
============
Unless stated elsewhere, file headers or otherwise, the license as stated in the LICENSE file.
[bcryptwiki]: http://en.wikipedia.org/wiki/Crypt_(Unix)#Blowfish-based_scheme
[bcryptgs]: http://mail-index.netbsd.org/tech-crypto/2002/05/24/msg000204.html
[codahale]: http://codahale.com/how-to-safely-store-a-password/
[gh13]: https://github.com/ncb000gt/node.bcrypt.js/issues/13
[jtr]: http://www.openwall.com/lists/oss-security/2011/06/20/2
[shadowfiend]:https://github.com/Shadowfiend
[thegoleffect]:https://github.com/thegoleffect
[pixelglow]:https://github.com/pixelglow
[dtrejo]:https://github.com/dtrejo
[alfredwesterveld]:https://github.com/alfredwesterveld
[newitfarmer]:https://github.com/newitfarmer
[zooko]:https://twitter.com/zooko
[vincentr]:https://twitter.com/vincentcr
[lloyd]:https://github.com/lloyd
[shtylman]:https://github.com/shtylman
[vadimg]:https://github.com/vadimg

6
staging/spec/fixtures/apps/node_native_dependencies/source/node_modules/bcrypt/bcrypt.js сгенерированный поставляемый Executable file
Просмотреть файл

@ -0,0 +1,6 @@
try {
module.exports = require('./build/default/bcrypt_lib');
} catch(e) {
//update for v0.5.5+
module.exports = require('./build/Release/bcrypt_lib');
}

40
staging/spec/fixtures/apps/node_native_dependencies/source/node_modules/bcrypt/package.json сгенерированный поставляемый Executable file
Просмотреть файл

@ -0,0 +1,40 @@
{
"name": "bcrypt",
"description": "A bcrypt library for NodeJS.",
"keywords": ["bcrypt","password","auth","authentication","encryption","crypt","crypto"],
"main": "./bcrypt",
"version": "0.4.0",
"author": "Nick Campbell (http://github.com/ncb000gt)",
"engines": { "node": ">= 0.4.0" },
"repository": {
"type": "git",
"url": "http://github.com/ncb000gt/node.bcrypt.js.git"
},
"licenses": [
{
"type": "MIT"
}
],
"bugs": {
"web" : "http://github.com/ncb000gt/node.bcrypt.js/issues"
},
"scripts": {
"install": "make build",
"test": "make test"
},
"devDependencies": {
"nodeunit": ">=0.5.4"
},
"contributors": [
"Antonio Salazar Cardozo <savedfastcool@gmail.com> (https://github.com/Shadowfiend)",
"Van Nguyen <the.gol.effect@gmail.com> (https://github.com/thegoleffect)",
"David Trejo <david@dtrejo.com> (https://github.com/dtrejo)",
"Ben Glow <glen.low@pixelglow.com> (https://github.com/pixelglow)",
"NewITFarmer.com <> (https://github.com/newitfarmer)",
"Alfred Westerveld <alfredwesterveld@gmail.com> (https://github.com/alfredwesterveld)",
"Vincent Côté-Roy <vincentcr@gmail.com> (https://github.com/vincentcr)",
"Lloyd Hilaiel <lloyd@hilaiel.com> (https://github.com/lloyd)",
"Roman Shtylman <shtylman@gmail.com> (https://github.com/shtylman)",
"Vadim Graboys <dimva13@gmail.com> (https://github.com/vadimg)"
]
}

326
staging/spec/fixtures/apps/node_native_dependencies/source/node_modules/bcrypt/src/bcrypt.cc сгенерированный поставляемый Executable file
Просмотреть файл

@ -0,0 +1,326 @@
/* $OpenBSD: bcrypt.c,v 1.24 2008/04/02 19:54:05 millert Exp $ */
/*
* Copyright 1997 Niels Provos <provos@physnet.uni-hamburg.de>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by Niels Provos.
* 4. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/* This password hashing algorithm was designed by David Mazieres
* <dm@lcs.mit.edu> and works as follows:
*
* 1. state := InitState ()
* 2. state := ExpandKey (state, salt, password) 3.
* REPEAT rounds:
* state := ExpandKey (state, 0, salt)
* state := ExpandKey(state, 0, password)
* 4. ctext := "OrpheanBeholderScryDoubt"
* 5. REPEAT 64:
* ctext := Encrypt_ECB (state, ctext);
* 6. RETURN Concatenate (salt, ctext);
*
*/
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <string.h>
#include <pwd.h>
#include <pthread.h>
#include "node_blf.h"
//#if !defined(__APPLE__) && !defined(__MACH__)
//#include "bsd/stdlib.h"
//#endif
/* This implementation is adaptable to current computing power.
* You can have up to 2^31 rounds which should be enough for some
* time to come.
*/
#define BCRYPT_VERSION '2'
#define BCRYPT_MAXSALT 16 /* Precomputation is just so nice */
#define BCRYPT_BLOCKS 6 /* Ciphertext blocks */
#define BCRYPT_MINROUNDS 16 /* we have log2(rounds) in salt */
/*char *bcrypt(const char *, const char *);
void encode_salt(char *, u_int8_t *, u_int16_t, u_int8_t);
char * bcrypt_gensalt(u_int8_t log_rounds);*/
static void encode_base64(u_int8_t *, u_int8_t *, u_int16_t);
static void decode_base64(u_int8_t *, u_int16_t, u_int8_t *);
const static char* error = ":";
const static u_int8_t Base64Code[] =
"./ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
const static u_int8_t index_64[128] = {
255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 0, 1, 54, 55,
56, 57, 58, 59, 60, 61, 62, 63, 255, 255,
255, 255, 255, 255, 255, 2, 3, 4, 5, 6,
7, 8, 9, 10, 11, 12, 13, 14, 15, 16,
17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27,
255, 255, 255, 255, 255, 255, 28, 29, 30,
31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
41, 42, 43, 44, 45, 46, 47, 48, 49, 50,
51, 52, 53, 255, 255, 255, 255, 255
};
#define CHAR64(c) ( (c) > 127 ? 255 : index_64[(c)])
static void
decode_base64(u_int8_t *buffer, u_int16_t len, u_int8_t *data)
{
u_int8_t *bp = buffer;
u_int8_t *p = data;
u_int8_t c1, c2, c3, c4;
while (bp < buffer + len) {
c1 = CHAR64(*p);
c2 = CHAR64(*(p + 1));
/* Invalid data */
if (c1 == 255 || c2 == 255)
break;
*bp++ = (c1 << 2) | ((c2 & 0x30) >> 4);
if (bp >= buffer + len)
break;
c3 = CHAR64(*(p + 2));
if (c3 == 255)
break;
*bp++ = ((c2 & 0x0f) << 4) | ((c3 & 0x3c) >> 2);
if (bp >= buffer + len)
break;
c4 = CHAR64(*(p + 3));
if (c4 == 255)
break;
*bp++ = ((c3 & 0x03) << 6) | c4;
p += 4;
}
}
void
encode_salt(char *salt, u_int8_t *csalt, u_int16_t clen, u_int8_t logr)
{
salt[0] = '$';
salt[1] = BCRYPT_VERSION;
salt[2] = 'a';
salt[3] = '$';
snprintf(salt + 4, 4, "%2.2u$", logr);
encode_base64((u_int8_t *) salt + 7, csalt, clen);
}
/* Generates a salt for this version of crypt.
Since versions may change. Keeping this here
seems sensible.
from: http://mail-index.netbsd.org/tech-crypto/2002/05/24/msg000204.html
*/
void
bcrypt_gensalt(u_int8_t log_rounds, u_int8_t *seed, char *gsalt)
{
if (log_rounds < 4)
log_rounds = 4;
else if (log_rounds > 31)
log_rounds = 31;
encode_salt(gsalt, seed, BCRYPT_MAXSALT, log_rounds);
}
/* We handle $Vers$log2(NumRounds)$salt+passwd$
i.e. $2$04$iwouldntknowwhattosayetKdJ6iFtacBqJdKe6aW7ou */
void
bcrypt(const char *key, const char *salt, char *encrypted)
{
blf_ctx state;
u_int32_t rounds, i, k;
u_int16_t j;
u_int8_t key_len, salt_len, logr, minor;
u_int8_t ciphertext[4 * BCRYPT_BLOCKS+1] = "OrpheanBeholderScryDoubt";
u_int8_t csalt[BCRYPT_MAXSALT];
u_int32_t cdata[BCRYPT_BLOCKS];
int n;
/* Discard "$" identifier */
salt++;
if (*salt > BCRYPT_VERSION) {
/* How do I handle errors ? Return ':' */
strcpy(encrypted, error);
return;
}
/* Check for minor versions */
if (salt[1] != '$') {
switch (salt[1]) {
case 'a':
/* 'ab' should not yield the same as 'abab' */
minor = salt[1];
salt++;
break;
default:
strcpy(encrypted, error);
return;
}
} else
minor = 0;
/* Discard version + "$" identifier */
salt += 2;
if (salt[2] != '$') {
/* Out of sync with passwd entry */
strcpy(encrypted, error);
return;
}
/* Computer power doesn't increase linear, 2^x should be fine */
n = atoi(salt);
if (n > 31 || n < 0) {
strcpy(encrypted, error);
return;
}
logr = (u_int8_t)n;
if ((rounds = (u_int32_t) 1 << logr) < BCRYPT_MINROUNDS) {
strcpy(encrypted, error);
return;
}
/* Discard num rounds + "$" identifier */
salt += 3;
if (strlen(salt) * 3 / 4 < BCRYPT_MAXSALT) {
strcpy(encrypted, error);
return;
}
/* We dont want the base64 salt but the raw data */
decode_base64(csalt, BCRYPT_MAXSALT, (u_int8_t *) salt);
salt_len = BCRYPT_MAXSALT;
key_len = strlen(key) + (minor >= 'a' ? 1 : 0);
/* Setting up S-Boxes and Subkeys */
Blowfish_initstate(&state);
Blowfish_expandstate(&state, csalt, salt_len,
(u_int8_t *) key, key_len);
for (k = 0; k < rounds; k++) {
Blowfish_expand0state(&state, (u_int8_t *) key, key_len);
Blowfish_expand0state(&state, csalt, salt_len);
}
/* This can be precomputed later */
j = 0;
for (i = 0; i < BCRYPT_BLOCKS; i++)
cdata[i] = Blowfish_stream2word(ciphertext, 4 * BCRYPT_BLOCKS, &j);
/* Now do the encryption */
for (k = 0; k < 64; k++)
blf_enc(&state, cdata, BCRYPT_BLOCKS / 2);
for (i = 0; i < BCRYPT_BLOCKS; i++) {
ciphertext[4 * i + 3] = cdata[i] & 0xff;
cdata[i] = cdata[i] >> 8;
ciphertext[4 * i + 2] = cdata[i] & 0xff;
cdata[i] = cdata[i] >> 8;
ciphertext[4 * i + 1] = cdata[i] & 0xff;
cdata[i] = cdata[i] >> 8;
ciphertext[4 * i + 0] = cdata[i] & 0xff;
}
i = 0;
encrypted[i++] = '$';
encrypted[i++] = BCRYPT_VERSION;
if (minor)
encrypted[i++] = minor;
encrypted[i++] = '$';
snprintf(encrypted + i, 4, "%2.2u$", logr);
encode_base64((u_int8_t *) encrypted + i + 3, csalt, BCRYPT_MAXSALT);
encode_base64((u_int8_t *) encrypted + strlen(encrypted), ciphertext,
4 * BCRYPT_BLOCKS - 1);
memset(&state, 0, sizeof(state));
memset(ciphertext, 0, sizeof(ciphertext));
memset(csalt, 0, sizeof(csalt));
memset(cdata, 0, sizeof(cdata));
}
u_int32_t bcrypt_get_rounds(const char * hash)
{
/* skip past the leading "$" */
if (!hash || *(hash++) != '$') return 0;
/* skip past version */
if (0 == (*hash++)) return 0;
if (*hash && *hash != '$') hash++;
if (*hash++ != '$') return 0;
return atoi(hash);
}
static void
encode_base64(u_int8_t *buffer, u_int8_t *data, u_int16_t len)
{
u_int8_t *bp = buffer;
u_int8_t *p = data;
u_int8_t c1, c2;
while (p < data + len) {
c1 = *p++;
*bp++ = Base64Code[(c1 >> 2)];
c1 = (c1 & 0x03) << 4;
if (p >= data + len) {
*bp++ = Base64Code[c1];
break;
}
c2 = *p++;
c1 |= (c2 >> 4) & 0x0f;
*bp++ = Base64Code[c1];
c1 = (c2 & 0x0f) << 2;
if (p >= data + len) {
*bp++ = Base64Code[c1];
break;
}
c2 = *p++;
c1 |= (c2 >> 6) & 0x03;
*bp++ = Base64Code[c1];
*bp++ = Base64Code[c2 & 0x3f];
}
*bp = '\0';
}

542
staging/spec/fixtures/apps/node_native_dependencies/source/node_modules/bcrypt/src/bcrypt_node.cc сгенерированный поставляемый Executable file
Просмотреть файл

@ -0,0 +1,542 @@
/*
* Copyright (c) 2010, Nicholas Campbell <nicholas.j.campbell@gmail.com>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the <ORGANIZATION> nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <node.h>
#include <node_version.h>
#include <ctype.h>
#include <string.h>
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include <openssl/rand.h>
#include "node_blf.h"
#define NODE_LESS_THAN (!(NODE_VERSION_AT_LEAST(0, 5, 4)))
using namespace v8;
using namespace node;
namespace {
struct base_request {
v8::Persistent<v8::Function> callback;
const char *error;
};
struct salt_request : base_request {
char *salt;
int salt_len;
int rand_len;
ssize_t rounds;
};
struct encrypt_request : base_request {
char *salt;
char *input;
char *output;
int output_len;
};
struct compare_request : base_request {
char *input;
char *encrypted;
bool result;
};
int GetSeed(u_int8_t *seed, int size) {
switch (RAND_bytes((unsigned char *)seed, size)) {
case -1:
case 0:
switch (RAND_pseudo_bytes(seed, size)) {
case -1:
return -1;
case 0:
return 0;
default:
return 1;
}
default:
return 1;
}
}
bool ValidateSalt(char *str) {
int count = 0;
bool valid = true;
int str_len = strlen(str);
char *new_str = (char *)malloc(str_len * sizeof(str));
memcpy(new_str, str, str_len * sizeof(str));
char *next_tok = new_str;
char *result = strsep(&next_tok, "$");
while (result != NULL) {
if (count == 1) {
//check version
if (!isdigit(result[0])) {
return false;
}
if (strlen(result) == 2 && !isalpha(result[1])) {
return false;
}
} else if (count == 2) {
//check rounds
if (!(isdigit(result[0]) && isdigit(result[1]))) {
return false;
}
}
count++;
result = strsep(&next_tok, "$");
}
free(new_str);
free(result);
return (count == 4);
}
/* SALT GENERATION */
#if NODE_LESS_THAN
int EIO_GenSalt(eio_req *req) {
#else
void EIO_GenSalt(eio_req *req) {
#endif
salt_request *s_req = (salt_request *)req->data;
char *salt = (char *)malloc(_SALT_LEN);
try {
u_int8_t *_seed = (u_int8_t *)malloc(s_req->rand_len * sizeof(u_int8_t));
switch(GetSeed(_seed, s_req->rand_len)) {
case -1:
s_req->error = "Rand operation not supported.";
case 0:
s_req->error = "Rand operation did not generate a cryptographically sound seed.";
}
bcrypt_gensalt(s_req->rounds, _seed, salt);
s_req->salt_len = strlen(salt);
s_req->salt = salt;
free(_seed);
} catch (const char *err) {
s_req->error = err;
free(salt);
}
#if NODE_LESS_THAN
return 0;
#endif
}
int EIO_GenSaltAfter(eio_req *req) {
HandleScope scope;
ev_unref(EV_DEFAULT_UC);
salt_request *s_req = (salt_request *)req->data;
Handle<Value> argv[2];
if (s_req->error) {
argv[0] = Exception::Error(String::New(s_req->error));
argv[1] = Undefined();
}
else {
argv[0] = Undefined();
argv[1] = Encode(s_req->salt, s_req->salt_len, BINARY);
}
TryCatch try_catch; // don't quite see the necessity of this
s_req->callback->Call(Context::GetCurrent()->Global(), 2, argv);
if (try_catch.HasCaught())
FatalException(try_catch);
s_req->callback.Dispose();
free(s_req->salt);
free(s_req);
return 0;
}
Handle<Value> GenerateSalt(const Arguments &args) {
HandleScope scope;
Local<Function> callback;
int rand_len = 20;
ssize_t rounds = 10;
if (args.Length() < 1) {
return ThrowException(Exception::Error(String::New("Must provide at least a callback.")));
} else if (args[0]->IsFunction()) {
callback = Local<Function>::Cast(args[0]);
} else if (args.Length() == 1) {
return ThrowException(Exception::Error(String::New("Must provide at least a callback.")));
}
if (args.Length() > 1) {
if (args[1]->IsFunction()) {
rounds = args[0]->Int32Value();
callback = Local<Function>::Cast(args[1]);
} else if (args.Length() > 2 && args[1]->IsNumber()) {
rand_len = args[1]->Int32Value();
if (args[2]->IsFunction()) {
callback = Local<Function>::Cast(args[2]);
} else {
return ThrowException(Exception::Error(String::New("No callback supplied.")));
}
} else {
return ThrowException(Exception::Error(String::New("No callback supplied.")));
}
}
salt_request *s_req = (salt_request *)malloc(sizeof(*s_req));
if (!s_req)
return ThrowException(Exception::Error(String::New("malloc in GenerateSalt failed.")));
s_req->callback = Persistent<Function>::New(callback);
s_req->rand_len = rand_len;
s_req->rounds = rounds;
s_req->error = NULL;
eio_custom(EIO_GenSalt, EIO_PRI_DEFAULT, EIO_GenSaltAfter, s_req);
ev_ref(EV_DEFAULT_UC);
return Undefined();
}
Handle<Value> GenerateSaltSync(const Arguments& args) {
HandleScope scope;
int size = 20;
ssize_t rounds = 10;
if (args.Length() < 1) {
return ThrowException(Exception::Error(String::New("Must give number of rounds.")));
} else if (!args[0]->IsNumber()) {
return ThrowException(Exception::Error(String::New("Param must be a number.")));
}
if (args.Length() > 0 && args[0]->IsNumber()) {
rounds = args[0]->Int32Value();
}
if (args.Length() > 1 && args[1]->IsNumber()) {
size = args[1]->Int32Value();
}
u_int8_t *_seed = (u_int8_t *)malloc(size * sizeof(u_int8_t));
switch(GetSeed(_seed, size)) {
case -1:
return ThrowException(Exception::Error(String::New("Rand operation not supported.")));
case 0:
return ThrowException(Exception::Error(String::New("Rand operation did not generate a cryptographically sound seed.")));
}
char salt[_SALT_LEN];
bcrypt_gensalt(rounds, _seed, salt);
int salt_len = strlen(salt);
free(_seed);
Local<Value> outString = Encode(salt, salt_len, BINARY);
return scope.Close(outString);
}
/* ENCRYPT DATA - USED TO BE HASHPW */
#if NODE_LESS_THAN
int EIO_Encrypt(eio_req *req) {
#else
void EIO_Encrypt(eio_req *req) {
#endif
encrypt_request *encrypt_req = (encrypt_request *)req->data;
if (!(ValidateSalt(encrypt_req->salt))) {
encrypt_req->error = "Invalid salt. Salt must be in the form of: $Vers$log2(NumRounds)$saltvalue";
#if NODE_LESS_THAN
return 1;
#else
return;
#endif
}
char* bcrypted = (char *)malloc(_PASSWORD_LEN);
try {
bcrypt((const char *)encrypt_req->input, (const char *)encrypt_req->salt, bcrypted);
encrypt_req->output_len = strlen(bcrypted);
encrypt_req->output = bcrypted;
} catch (const char *err) {
encrypt_req->error = err;
free(bcrypted);
}
#if NODE_LESS_THAN
return 0;
#endif
}
int EIO_EncryptAfter(eio_req *req) {
HandleScope scope;
ev_unref(EV_DEFAULT_UC);
encrypt_request *encrypt_req = (encrypt_request *)req->data;
Handle<Value> argv[2];
if (encrypt_req->error != NULL) {
argv[0] = Exception::Error(String::New(encrypt_req->error));
argv[1] = Undefined();
}
else {
argv[0] = Undefined();
argv[1] = Encode(encrypt_req->output, encrypt_req->output_len, BINARY);
}
TryCatch try_catch; // don't quite see the necessity of this
encrypt_req->callback->Call(Context::GetCurrent()->Global(), 2, argv);
if (try_catch.HasCaught())
FatalException(try_catch);
encrypt_req->callback.Dispose();
free(encrypt_req->salt);
free(encrypt_req->input);
free(encrypt_req->output);
free(encrypt_req);
return 0;
}
Handle<Value> Encrypt(const Arguments& args) {
HandleScope scope;
if (args.Length() < 3) {
return ThrowException(Exception::Error(String::New("Must give data, salt and callback.")));
} else if (!args[0]->IsString() || !args[1]->IsString() || !args[2]->IsFunction()) {
return ThrowException(Exception::Error(String::New("Data and salt must be strings and the callback must be a function.")));
}
String::Utf8Value data(args[0]->ToString());
String::Utf8Value salt(args[1]->ToString());
Local<Function> callback = Local<Function>::Cast(args[2]);
encrypt_request *encrypt_req = (encrypt_request *)malloc(sizeof(*encrypt_req));
if (!encrypt_req)
return ThrowException(Exception::Error(String::New("malloc in Encrypt failed.")));
encrypt_req->callback = Persistent<Function>::New(callback);
encrypt_req->input = strdup(*data);
encrypt_req->salt = strdup(*salt);
encrypt_req->output = NULL;
encrypt_req->error = NULL;
eio_custom(EIO_Encrypt, EIO_PRI_DEFAULT, EIO_EncryptAfter, encrypt_req);
ev_ref(EV_DEFAULT_UC);
return Undefined();
}
Handle<Value> EncryptSync(const Arguments& args) {
HandleScope scope;
if (args.Length() < 2) {
return ThrowException(Exception::Error(String::New("Must give password and salt.")));
} else if (!args[0]->IsString() || !args[1]->IsString()) {
return ThrowException(Exception::Error(String::New("Params must be strings.")));
}
String::Utf8Value data(args[0]->ToString());
String::Utf8Value salt(args[1]->ToString());
if (!(ValidateSalt(*salt))) {
return ThrowException(Exception::Error(String::New("Invalid salt. Salt must be in the form of: $Vers$log2(NumRounds)$saltvalue")));
}
char bcrypted[_PASSWORD_LEN];
bcrypt(*data, *salt, bcrypted);
int bcrypted_len = strlen(bcrypted);
Local<Value> outString = Encode(bcrypted, bcrypted_len, BINARY);
return scope.Close(outString);
}
/* COMPARATOR */
bool CompareStrings(char* s1, char* s2) {
bool eq = true;
int s1_len = strlen(s1);
int s2_len = strlen(s2);
if (s1_len != s2_len) {
eq = false;
}
int max_len = (s2_len < s1_len)?s1_len:s2_len;
for (int i = 0; i < max_len; i++) {
if (s1_len >= i && s2_len >= i && s1[i] != s2[i]) {
eq = false;
}
}
return eq;
}
#if NODE_LESS_THAN
int EIO_Compare(eio_req *req) {
#else
void EIO_Compare(eio_req *req) {
#endif
compare_request *compare_req = (compare_request *)req->data;
try {
char bcrypted[_PASSWORD_LEN];
bcrypt((const char *)compare_req->input, (const char *)compare_req->encrypted, bcrypted);
compare_req->result = CompareStrings(bcrypted, (char *)compare_req->encrypted);
} catch (const char *err) {
compare_req->error = err;
}
#if NODE_LESS_THAN
return 0;
#endif
}
int EIO_CompareAfter(eio_req *req) {
HandleScope scope;
ev_unref(EV_DEFAULT_UC);
compare_request *compare_req = (compare_request *)req->data;
Handle<Value> argv[2];
if (compare_req->error) {
argv[0] = Exception::Error(String::New(compare_req->error));
argv[1] = Undefined();
} else {
argv[0] = Undefined();
if (compare_req->result) {
argv[1] = Boolean::New(true);
} else {
argv[1] = Boolean::New(false);
}
}
TryCatch try_catch; // don't quite see the necessity of this
compare_req->callback->Call(Context::GetCurrent()->Global(), 2, argv);
if (try_catch.HasCaught())
FatalException(try_catch);
compare_req->callback.Dispose();
free(compare_req->encrypted);
free(compare_req->input);
free(compare_req);
return 0;
}
Handle<Value> Compare(const Arguments& args) {
HandleScope scope;
if (args.Length() < 3) {
return ThrowException(Exception::Error(String::New("Must give input, data and callback.")));
} else if (!args[0]->IsString() || !args[1]->IsString() || !args[2]->IsFunction()) {
return ThrowException(Exception::Error(String::New("Input and data to compare against must be strings and the callback must be a function.")));
}
String::Utf8Value input(args[0]->ToString());
String::Utf8Value encrypted(args[1]->ToString());
Local<Function> callback = Local<Function>::Cast(args[2]);
compare_request *compare_req = (compare_request *)malloc(sizeof(*compare_req));
if (!compare_req)
return ThrowException(Exception::Error(String::New("malloc in Compare failed.")));
compare_req->callback = Persistent<Function>::New(callback);
compare_req->input = strdup(*input);
compare_req->encrypted = strdup(*encrypted);
compare_req->error = NULL;
eio_custom(EIO_Compare, EIO_PRI_DEFAULT, EIO_CompareAfter, compare_req);
ev_ref(EV_DEFAULT_UC);
return Undefined();
}
Handle<Value> CompareSync(const Arguments& args) {
HandleScope scope;
if (args.Length() < 2) {
return ThrowException(Exception::Error(String::New("Must give password and hash.")));
} else if (!args[0]->IsString() || !args[1]->IsString()) {
return ThrowException(Exception::Error(String::New("Params must be strings.")));
}
String::Utf8Value pw(args[0]->ToString());
String::Utf8Value hash(args[1]->ToString());
char bcrypted[_PASSWORD_LEN];
bcrypt(*pw, *hash, bcrypted);
return Boolean::New(CompareStrings(bcrypted, *hash));
}
Handle<Value> GetRounds(const Arguments& args) {
HandleScope scope;
if (args.Length() < 1) {
return ThrowException(Exception::Error(String::New("Must provide hash.")));
} else if (!args[0]->IsString()) {
return ThrowException(Exception::Error(String::New("Hash must be a string.")));
}
String::Utf8Value hash(args[0]->ToString());
u_int32_t rounds;
if (!(rounds = bcrypt_get_rounds(*hash))) {
return ThrowException(Exception::Error(String::New("invalid hash provided")));
}
return Integer::New(rounds);
}
} // anonymous namespace
// bind the bcrypt module
extern "C" void init(Handle<Object> target) {
HandleScope scope;
NODE_SET_METHOD(target, "gen_salt_sync", GenerateSaltSync);
NODE_SET_METHOD(target, "encrypt_sync", EncryptSync);
NODE_SET_METHOD(target, "compare_sync", CompareSync);
NODE_SET_METHOD(target, "get_rounds", GetRounds);
NODE_SET_METHOD(target, "gen_salt", GenerateSalt);
NODE_SET_METHOD(target, "encrypt", Encrypt);
NODE_SET_METHOD(target, "compare", Compare);
};

686
staging/spec/fixtures/apps/node_native_dependencies/source/node_modules/bcrypt/src/blowfish.cc сгенерированный поставляемый Executable file
Просмотреть файл

@ -0,0 +1,686 @@
/* $OpenBSD: blowfish.c,v 1.18 2004/11/02 17:23:26 hshoexer Exp $ */
/*
* Blowfish block cipher for OpenBSD
* Copyright 1997 Niels Provos <provos@physnet.uni-hamburg.de>
* All rights reserved.
*
* Implementation advice by David Mazieres <dm@lcs.mit.edu>.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by Niels Provos.
* 4. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/*
* This code is derived from section 14.3 and the given source
* in section V of Applied Cryptography, second edition.
* Blowfish is an unpatented fast block cipher designed by
* Bruce Schneier.
*/
#if 0
#include <stdio.h> /* used for debugging */
#include <string.h>
#endif
#include <sys/types.h>
#include "node_blf.h"
#undef inline
#ifdef __GNUC__
#define inline __inline
#else /* !__GNUC__ */
#define inline
#endif /* !__GNUC__ */
/* Function for Feistel Networks */
#define F(s, x) ((((s)[ (((x)>>24)&0xFF)] \
+ (s)[0x100 + (((x)>>16)&0xFF)]) \
^ (s)[0x200 + (((x)>> 8)&0xFF)]) \
+ (s)[0x300 + ( (x) &0xFF)])
#define BLFRND(s,p,i,j,n) (i ^= F(s,j) ^ (p)[n])
void
Blowfish_encipher(blf_ctx *c, u_int32_t *xl, u_int32_t *xr)
{
u_int32_t Xl;
u_int32_t Xr;
u_int32_t *s = c->S[0];
u_int32_t *p = c->P;
Xl = *xl;
Xr = *xr;
Xl ^= p[0];
BLFRND(s, p, Xr, Xl, 1); BLFRND(s, p, Xl, Xr, 2);
BLFRND(s, p, Xr, Xl, 3); BLFRND(s, p, Xl, Xr, 4);
BLFRND(s, p, Xr, Xl, 5); BLFRND(s, p, Xl, Xr, 6);
BLFRND(s, p, Xr, Xl, 7); BLFRND(s, p, Xl, Xr, 8);
BLFRND(s, p, Xr, Xl, 9); BLFRND(s, p, Xl, Xr, 10);
BLFRND(s, p, Xr, Xl, 11); BLFRND(s, p, Xl, Xr, 12);
BLFRND(s, p, Xr, Xl, 13); BLFRND(s, p, Xl, Xr, 14);
BLFRND(s, p, Xr, Xl, 15); BLFRND(s, p, Xl, Xr, 16);
*xl = Xr ^ p[17];
*xr = Xl;
}
void
Blowfish_decipher(blf_ctx *c, u_int32_t *xl, u_int32_t *xr)
{
u_int32_t Xl;
u_int32_t Xr;
u_int32_t *s = c->S[0];
u_int32_t *p = c->P;
Xl = *xl;
Xr = *xr;
Xl ^= p[17];
BLFRND(s, p, Xr, Xl, 16); BLFRND(s, p, Xl, Xr, 15);
BLFRND(s, p, Xr, Xl, 14); BLFRND(s, p, Xl, Xr, 13);
BLFRND(s, p, Xr, Xl, 12); BLFRND(s, p, Xl, Xr, 11);
BLFRND(s, p, Xr, Xl, 10); BLFRND(s, p, Xl, Xr, 9);
BLFRND(s, p, Xr, Xl, 8); BLFRND(s, p, Xl, Xr, 7);
BLFRND(s, p, Xr, Xl, 6); BLFRND(s, p, Xl, Xr, 5);
BLFRND(s, p, Xr, Xl, 4); BLFRND(s, p, Xl, Xr, 3);
BLFRND(s, p, Xr, Xl, 2); BLFRND(s, p, Xl, Xr, 1);
*xl = Xr ^ p[0];
*xr = Xl;
}
void
Blowfish_initstate(blf_ctx *c)
{
/* P-box and S-box tables initialized with digits of Pi */
static const blf_ctx initstate =
{ {
{
0xd1310ba6, 0x98dfb5ac, 0x2ffd72db, 0xd01adfb7,
0xb8e1afed, 0x6a267e96, 0xba7c9045, 0xf12c7f99,
0x24a19947, 0xb3916cf7, 0x0801f2e2, 0x858efc16,
0x636920d8, 0x71574e69, 0xa458fea3, 0xf4933d7e,
0x0d95748f, 0x728eb658, 0x718bcd58, 0x82154aee,
0x7b54a41d, 0xc25a59b5, 0x9c30d539, 0x2af26013,
0xc5d1b023, 0x286085f0, 0xca417918, 0xb8db38ef,
0x8e79dcb0, 0x603a180e, 0x6c9e0e8b, 0xb01e8a3e,
0xd71577c1, 0xbd314b27, 0x78af2fda, 0x55605c60,
0xe65525f3, 0xaa55ab94, 0x57489862, 0x63e81440,
0x55ca396a, 0x2aab10b6, 0xb4cc5c34, 0x1141e8ce,
0xa15486af, 0x7c72e993, 0xb3ee1411, 0x636fbc2a,
0x2ba9c55d, 0x741831f6, 0xce5c3e16, 0x9b87931e,
0xafd6ba33, 0x6c24cf5c, 0x7a325381, 0x28958677,
0x3b8f4898, 0x6b4bb9af, 0xc4bfe81b, 0x66282193,
0x61d809cc, 0xfb21a991, 0x487cac60, 0x5dec8032,
0xef845d5d, 0xe98575b1, 0xdc262302, 0xeb651b88,
0x23893e81, 0xd396acc5, 0x0f6d6ff3, 0x83f44239,
0x2e0b4482, 0xa4842004, 0x69c8f04a, 0x9e1f9b5e,
0x21c66842, 0xf6e96c9a, 0x670c9c61, 0xabd388f0,
0x6a51a0d2, 0xd8542f68, 0x960fa728, 0xab5133a3,
0x6eef0b6c, 0x137a3be4, 0xba3bf050, 0x7efb2a98,
0xa1f1651d, 0x39af0176, 0x66ca593e, 0x82430e88,
0x8cee8619, 0x456f9fb4, 0x7d84a5c3, 0x3b8b5ebe,
0xe06f75d8, 0x85c12073, 0x401a449f, 0x56c16aa6,
0x4ed3aa62, 0x363f7706, 0x1bfedf72, 0x429b023d,
0x37d0d724, 0xd00a1248, 0xdb0fead3, 0x49f1c09b,
0x075372c9, 0x80991b7b, 0x25d479d8, 0xf6e8def7,
0xe3fe501a, 0xb6794c3b, 0x976ce0bd, 0x04c006ba,
0xc1a94fb6, 0x409f60c4, 0x5e5c9ec2, 0x196a2463,
0x68fb6faf, 0x3e6c53b5, 0x1339b2eb, 0x3b52ec6f,
0x6dfc511f, 0x9b30952c, 0xcc814544, 0xaf5ebd09,
0xbee3d004, 0xde334afd, 0x660f2807, 0x192e4bb3,
0xc0cba857, 0x45c8740f, 0xd20b5f39, 0xb9d3fbdb,
0x5579c0bd, 0x1a60320a, 0xd6a100c6, 0x402c7279,
0x679f25fe, 0xfb1fa3cc, 0x8ea5e9f8, 0xdb3222f8,
0x3c7516df, 0xfd616b15, 0x2f501ec8, 0xad0552ab,
0x323db5fa, 0xfd238760, 0x53317b48, 0x3e00df82,
0x9e5c57bb, 0xca6f8ca0, 0x1a87562e, 0xdf1769db,
0xd542a8f6, 0x287effc3, 0xac6732c6, 0x8c4f5573,
0x695b27b0, 0xbbca58c8, 0xe1ffa35d, 0xb8f011a0,
0x10fa3d98, 0xfd2183b8, 0x4afcb56c, 0x2dd1d35b,
0x9a53e479, 0xb6f84565, 0xd28e49bc, 0x4bfb9790,
0xe1ddf2da, 0xa4cb7e33, 0x62fb1341, 0xcee4c6e8,
0xef20cada, 0x36774c01, 0xd07e9efe, 0x2bf11fb4,
0x95dbda4d, 0xae909198, 0xeaad8e71, 0x6b93d5a0,
0xd08ed1d0, 0xafc725e0, 0x8e3c5b2f, 0x8e7594b7,
0x8ff6e2fb, 0xf2122b64, 0x8888b812, 0x900df01c,
0x4fad5ea0, 0x688fc31c, 0xd1cff191, 0xb3a8c1ad,
0x2f2f2218, 0xbe0e1777, 0xea752dfe, 0x8b021fa1,
0xe5a0cc0f, 0xb56f74e8, 0x18acf3d6, 0xce89e299,
0xb4a84fe0, 0xfd13e0b7, 0x7cc43b81, 0xd2ada8d9,
0x165fa266, 0x80957705, 0x93cc7314, 0x211a1477,
0xe6ad2065, 0x77b5fa86, 0xc75442f5, 0xfb9d35cf,
0xebcdaf0c, 0x7b3e89a0, 0xd6411bd3, 0xae1e7e49,
0x00250e2d, 0x2071b35e, 0x226800bb, 0x57b8e0af,
0x2464369b, 0xf009b91e, 0x5563911d, 0x59dfa6aa,
0x78c14389, 0xd95a537f, 0x207d5ba2, 0x02e5b9c5,
0x83260376, 0x6295cfa9, 0x11c81968, 0x4e734a41,
0xb3472dca, 0x7b14a94a, 0x1b510052, 0x9a532915,
0xd60f573f, 0xbc9bc6e4, 0x2b60a476, 0x81e67400,
0x08ba6fb5, 0x571be91f, 0xf296ec6b, 0x2a0dd915,
0xb6636521, 0xe7b9f9b6, 0xff34052e, 0xc5855664,
0x53b02d5d, 0xa99f8fa1, 0x08ba4799, 0x6e85076a},
{
0x4b7a70e9, 0xb5b32944, 0xdb75092e, 0xc4192623,
0xad6ea6b0, 0x49a7df7d, 0x9cee60b8, 0x8fedb266,
0xecaa8c71, 0x699a17ff, 0x5664526c, 0xc2b19ee1,
0x193602a5, 0x75094c29, 0xa0591340, 0xe4183a3e,
0x3f54989a, 0x5b429d65, 0x6b8fe4d6, 0x99f73fd6,
0xa1d29c07, 0xefe830f5, 0x4d2d38e6, 0xf0255dc1,
0x4cdd2086, 0x8470eb26, 0x6382e9c6, 0x021ecc5e,
0x09686b3f, 0x3ebaefc9, 0x3c971814, 0x6b6a70a1,
0x687f3584, 0x52a0e286, 0xb79c5305, 0xaa500737,
0x3e07841c, 0x7fdeae5c, 0x8e7d44ec, 0x5716f2b8,
0xb03ada37, 0xf0500c0d, 0xf01c1f04, 0x0200b3ff,
0xae0cf51a, 0x3cb574b2, 0x25837a58, 0xdc0921bd,
0xd19113f9, 0x7ca92ff6, 0x94324773, 0x22f54701,
0x3ae5e581, 0x37c2dadc, 0xc8b57634, 0x9af3dda7,
0xa9446146, 0x0fd0030e, 0xecc8c73e, 0xa4751e41,
0xe238cd99, 0x3bea0e2f, 0x3280bba1, 0x183eb331,
0x4e548b38, 0x4f6db908, 0x6f420d03, 0xf60a04bf,
0x2cb81290, 0x24977c79, 0x5679b072, 0xbcaf89af,
0xde9a771f, 0xd9930810, 0xb38bae12, 0xdccf3f2e,
0x5512721f, 0x2e6b7124, 0x501adde6, 0x9f84cd87,
0x7a584718, 0x7408da17, 0xbc9f9abc, 0xe94b7d8c,
0xec7aec3a, 0xdb851dfa, 0x63094366, 0xc464c3d2,
0xef1c1847, 0x3215d908, 0xdd433b37, 0x24c2ba16,
0x12a14d43, 0x2a65c451, 0x50940002, 0x133ae4dd,
0x71dff89e, 0x10314e55, 0x81ac77d6, 0x5f11199b,
0x043556f1, 0xd7a3c76b, 0x3c11183b, 0x5924a509,
0xf28fe6ed, 0x97f1fbfa, 0x9ebabf2c, 0x1e153c6e,
0x86e34570, 0xeae96fb1, 0x860e5e0a, 0x5a3e2ab3,
0x771fe71c, 0x4e3d06fa, 0x2965dcb9, 0x99e71d0f,
0x803e89d6, 0x5266c825, 0x2e4cc978, 0x9c10b36a,
0xc6150eba, 0x94e2ea78, 0xa5fc3c53, 0x1e0a2df4,
0xf2f74ea7, 0x361d2b3d, 0x1939260f, 0x19c27960,
0x5223a708, 0xf71312b6, 0xebadfe6e, 0xeac31f66,
0xe3bc4595, 0xa67bc883, 0xb17f37d1, 0x018cff28,
0xc332ddef, 0xbe6c5aa5, 0x65582185, 0x68ab9802,
0xeecea50f, 0xdb2f953b, 0x2aef7dad, 0x5b6e2f84,
0x1521b628, 0x29076170, 0xecdd4775, 0x619f1510,
0x13cca830, 0xeb61bd96, 0x0334fe1e, 0xaa0363cf,
0xb5735c90, 0x4c70a239, 0xd59e9e0b, 0xcbaade14,
0xeecc86bc, 0x60622ca7, 0x9cab5cab, 0xb2f3846e,
0x648b1eaf, 0x19bdf0ca, 0xa02369b9, 0x655abb50,
0x40685a32, 0x3c2ab4b3, 0x319ee9d5, 0xc021b8f7,
0x9b540b19, 0x875fa099, 0x95f7997e, 0x623d7da8,
0xf837889a, 0x97e32d77, 0x11ed935f, 0x16681281,
0x0e358829, 0xc7e61fd6, 0x96dedfa1, 0x7858ba99,
0x57f584a5, 0x1b227263, 0x9b83c3ff, 0x1ac24696,
0xcdb30aeb, 0x532e3054, 0x8fd948e4, 0x6dbc3128,
0x58ebf2ef, 0x34c6ffea, 0xfe28ed61, 0xee7c3c73,
0x5d4a14d9, 0xe864b7e3, 0x42105d14, 0x203e13e0,
0x45eee2b6, 0xa3aaabea, 0xdb6c4f15, 0xfacb4fd0,
0xc742f442, 0xef6abbb5, 0x654f3b1d, 0x41cd2105,
0xd81e799e, 0x86854dc7, 0xe44b476a, 0x3d816250,
0xcf62a1f2, 0x5b8d2646, 0xfc8883a0, 0xc1c7b6a3,
0x7f1524c3, 0x69cb7492, 0x47848a0b, 0x5692b285,
0x095bbf00, 0xad19489d, 0x1462b174, 0x23820e00,
0x58428d2a, 0x0c55f5ea, 0x1dadf43e, 0x233f7061,
0x3372f092, 0x8d937e41, 0xd65fecf1, 0x6c223bdb,
0x7cde3759, 0xcbee7460, 0x4085f2a7, 0xce77326e,
0xa6078084, 0x19f8509e, 0xe8efd855, 0x61d99735,
0xa969a7aa, 0xc50c06c2, 0x5a04abfc, 0x800bcadc,
0x9e447a2e, 0xc3453484, 0xfdd56705, 0x0e1e9ec9,
0xdb73dbd3, 0x105588cd, 0x675fda79, 0xe3674340,
0xc5c43465, 0x713e38d8, 0x3d28f89e, 0xf16dff20,
0x153e21e7, 0x8fb03d4a, 0xe6e39f2b, 0xdb83adf7},
{
0xe93d5a68, 0x948140f7, 0xf64c261c, 0x94692934,
0x411520f7, 0x7602d4f7, 0xbcf46b2e, 0xd4a20068,
0xd4082471, 0x3320f46a, 0x43b7d4b7, 0x500061af,
0x1e39f62e, 0x97244546, 0x14214f74, 0xbf8b8840,
0x4d95fc1d, 0x96b591af, 0x70f4ddd3, 0x66a02f45,
0xbfbc09ec, 0x03bd9785, 0x7fac6dd0, 0x31cb8504,
0x96eb27b3, 0x55fd3941, 0xda2547e6, 0xabca0a9a,
0x28507825, 0x530429f4, 0x0a2c86da, 0xe9b66dfb,
0x68dc1462, 0xd7486900, 0x680ec0a4, 0x27a18dee,
0x4f3ffea2, 0xe887ad8c, 0xb58ce006, 0x7af4d6b6,
0xaace1e7c, 0xd3375fec, 0xce78a399, 0x406b2a42,
0x20fe9e35, 0xd9f385b9, 0xee39d7ab, 0x3b124e8b,
0x1dc9faf7, 0x4b6d1856, 0x26a36631, 0xeae397b2,
0x3a6efa74, 0xdd5b4332, 0x6841e7f7, 0xca7820fb,
0xfb0af54e, 0xd8feb397, 0x454056ac, 0xba489527,
0x55533a3a, 0x20838d87, 0xfe6ba9b7, 0xd096954b,
0x55a867bc, 0xa1159a58, 0xcca92963, 0x99e1db33,
0xa62a4a56, 0x3f3125f9, 0x5ef47e1c, 0x9029317c,
0xfdf8e802, 0x04272f70, 0x80bb155c, 0x05282ce3,
0x95c11548, 0xe4c66d22, 0x48c1133f, 0xc70f86dc,
0x07f9c9ee, 0x41041f0f, 0x404779a4, 0x5d886e17,
0x325f51eb, 0xd59bc0d1, 0xf2bcc18f, 0x41113564,
0x257b7834, 0x602a9c60, 0xdff8e8a3, 0x1f636c1b,
0x0e12b4c2, 0x02e1329e, 0xaf664fd1, 0xcad18115,
0x6b2395e0, 0x333e92e1, 0x3b240b62, 0xeebeb922,
0x85b2a20e, 0xe6ba0d99, 0xde720c8c, 0x2da2f728,
0xd0127845, 0x95b794fd, 0x647d0862, 0xe7ccf5f0,
0x5449a36f, 0x877d48fa, 0xc39dfd27, 0xf33e8d1e,
0x0a476341, 0x992eff74, 0x3a6f6eab, 0xf4f8fd37,
0xa812dc60, 0xa1ebddf8, 0x991be14c, 0xdb6e6b0d,
0xc67b5510, 0x6d672c37, 0x2765d43b, 0xdcd0e804,
0xf1290dc7, 0xcc00ffa3, 0xb5390f92, 0x690fed0b,
0x667b9ffb, 0xcedb7d9c, 0xa091cf0b, 0xd9155ea3,
0xbb132f88, 0x515bad24, 0x7b9479bf, 0x763bd6eb,
0x37392eb3, 0xcc115979, 0x8026e297, 0xf42e312d,
0x6842ada7, 0xc66a2b3b, 0x12754ccc, 0x782ef11c,
0x6a124237, 0xb79251e7, 0x06a1bbe6, 0x4bfb6350,
0x1a6b1018, 0x11caedfa, 0x3d25bdd8, 0xe2e1c3c9,
0x44421659, 0x0a121386, 0xd90cec6e, 0xd5abea2a,
0x64af674e, 0xda86a85f, 0xbebfe988, 0x64e4c3fe,
0x9dbc8057, 0xf0f7c086, 0x60787bf8, 0x6003604d,
0xd1fd8346, 0xf6381fb0, 0x7745ae04, 0xd736fccc,
0x83426b33, 0xf01eab71, 0xb0804187, 0x3c005e5f,
0x77a057be, 0xbde8ae24, 0x55464299, 0xbf582e61,
0x4e58f48f, 0xf2ddfda2, 0xf474ef38, 0x8789bdc2,
0x5366f9c3, 0xc8b38e74, 0xb475f255, 0x46fcd9b9,
0x7aeb2661, 0x8b1ddf84, 0x846a0e79, 0x915f95e2,
0x466e598e, 0x20b45770, 0x8cd55591, 0xc902de4c,
0xb90bace1, 0xbb8205d0, 0x11a86248, 0x7574a99e,
0xb77f19b6, 0xe0a9dc09, 0x662d09a1, 0xc4324633,
0xe85a1f02, 0x09f0be8c, 0x4a99a025, 0x1d6efe10,
0x1ab93d1d, 0x0ba5a4df, 0xa186f20f, 0x2868f169,
0xdcb7da83, 0x573906fe, 0xa1e2ce9b, 0x4fcd7f52,
0x50115e01, 0xa70683fa, 0xa002b5c4, 0x0de6d027,
0x9af88c27, 0x773f8641, 0xc3604c06, 0x61a806b5,
0xf0177a28, 0xc0f586e0, 0x006058aa, 0x30dc7d62,
0x11e69ed7, 0x2338ea63, 0x53c2dd94, 0xc2c21634,
0xbbcbee56, 0x90bcb6de, 0xebfc7da1, 0xce591d76,
0x6f05e409, 0x4b7c0188, 0x39720a3d, 0x7c927c24,
0x86e3725f, 0x724d9db9, 0x1ac15bb4, 0xd39eb8fc,
0xed545578, 0x08fca5b5, 0xd83d7cd3, 0x4dad0fc4,
0x1e50ef5e, 0xb161e6f8, 0xa28514d9, 0x6c51133c,
0x6fd5c7e7, 0x56e14ec4, 0x362abfce, 0xddc6c837,
0xd79a3234, 0x92638212, 0x670efa8e, 0x406000e0},
{
0x3a39ce37, 0xd3faf5cf, 0xabc27737, 0x5ac52d1b,
0x5cb0679e, 0x4fa33742, 0xd3822740, 0x99bc9bbe,
0xd5118e9d, 0xbf0f7315, 0xd62d1c7e, 0xc700c47b,
0xb78c1b6b, 0x21a19045, 0xb26eb1be, 0x6a366eb4,
0x5748ab2f, 0xbc946e79, 0xc6a376d2, 0x6549c2c8,
0x530ff8ee, 0x468dde7d, 0xd5730a1d, 0x4cd04dc6,
0x2939bbdb, 0xa9ba4650, 0xac9526e8, 0xbe5ee304,
0xa1fad5f0, 0x6a2d519a, 0x63ef8ce2, 0x9a86ee22,
0xc089c2b8, 0x43242ef6, 0xa51e03aa, 0x9cf2d0a4,
0x83c061ba, 0x9be96a4d, 0x8fe51550, 0xba645bd6,
0x2826a2f9, 0xa73a3ae1, 0x4ba99586, 0xef5562e9,
0xc72fefd3, 0xf752f7da, 0x3f046f69, 0x77fa0a59,
0x80e4a915, 0x87b08601, 0x9b09e6ad, 0x3b3ee593,
0xe990fd5a, 0x9e34d797, 0x2cf0b7d9, 0x022b8b51,
0x96d5ac3a, 0x017da67d, 0xd1cf3ed6, 0x7c7d2d28,
0x1f9f25cf, 0xadf2b89b, 0x5ad6b472, 0x5a88f54c,
0xe029ac71, 0xe019a5e6, 0x47b0acfd, 0xed93fa9b,
0xe8d3c48d, 0x283b57cc, 0xf8d56629, 0x79132e28,
0x785f0191, 0xed756055, 0xf7960e44, 0xe3d35e8c,
0x15056dd4, 0x88f46dba, 0x03a16125, 0x0564f0bd,
0xc3eb9e15, 0x3c9057a2, 0x97271aec, 0xa93a072a,
0x1b3f6d9b, 0x1e6321f5, 0xf59c66fb, 0x26dcf319,
0x7533d928, 0xb155fdf5, 0x03563482, 0x8aba3cbb,
0x28517711, 0xc20ad9f8, 0xabcc5167, 0xccad925f,
0x4de81751, 0x3830dc8e, 0x379d5862, 0x9320f991,
0xea7a90c2, 0xfb3e7bce, 0x5121ce64, 0x774fbe32,
0xa8b6e37e, 0xc3293d46, 0x48de5369, 0x6413e680,
0xa2ae0810, 0xdd6db224, 0x69852dfd, 0x09072166,
0xb39a460a, 0x6445c0dd, 0x586cdecf, 0x1c20c8ae,
0x5bbef7dd, 0x1b588d40, 0xccd2017f, 0x6bb4e3bb,
0xdda26a7e, 0x3a59ff45, 0x3e350a44, 0xbcb4cdd5,
0x72eacea8, 0xfa6484bb, 0x8d6612ae, 0xbf3c6f47,
0xd29be463, 0x542f5d9e, 0xaec2771b, 0xf64e6370,
0x740e0d8d, 0xe75b1357, 0xf8721671, 0xaf537d5d,
0x4040cb08, 0x4eb4e2cc, 0x34d2466a, 0x0115af84,
0xe1b00428, 0x95983a1d, 0x06b89fb4, 0xce6ea048,
0x6f3f3b82, 0x3520ab82, 0x011a1d4b, 0x277227f8,
0x611560b1, 0xe7933fdc, 0xbb3a792b, 0x344525bd,
0xa08839e1, 0x51ce794b, 0x2f32c9b7, 0xa01fbac9,
0xe01cc87e, 0xbcc7d1f6, 0xcf0111c3, 0xa1e8aac7,
0x1a908749, 0xd44fbd9a, 0xd0dadecb, 0xd50ada38,
0x0339c32a, 0xc6913667, 0x8df9317c, 0xe0b12b4f,
0xf79e59b7, 0x43f5bb3a, 0xf2d519ff, 0x27d9459c,
0xbf97222c, 0x15e6fc2a, 0x0f91fc71, 0x9b941525,
0xfae59361, 0xceb69ceb, 0xc2a86459, 0x12baa8d1,
0xb6c1075e, 0xe3056a0c, 0x10d25065, 0xcb03a442,
0xe0ec6e0e, 0x1698db3b, 0x4c98a0be, 0x3278e964,
0x9f1f9532, 0xe0d392df, 0xd3a0342b, 0x8971f21e,
0x1b0a7441, 0x4ba3348c, 0xc5be7120, 0xc37632d8,
0xdf359f8d, 0x9b992f2e, 0xe60b6f47, 0x0fe3f11d,
0xe54cda54, 0x1edad891, 0xce6279cf, 0xcd3e7e6f,
0x1618b166, 0xfd2c1d05, 0x848fd2c5, 0xf6fb2299,
0xf523f357, 0xa6327623, 0x93a83531, 0x56cccd02,
0xacf08162, 0x5a75ebb5, 0x6e163697, 0x88d273cc,
0xde966292, 0x81b949d0, 0x4c50901b, 0x71c65614,
0xe6c6c7bd, 0x327a140a, 0x45e1d006, 0xc3f27b9a,
0xc9aa53fd, 0x62a80f00, 0xbb25bfe2, 0x35bdd2f6,
0x71126905, 0xb2040222, 0xb6cbcf7c, 0xcd769c2b,
0x53113ec0, 0x1640e3d3, 0x38abbd60, 0x2547adf0,
0xba38209c, 0xf746ce76, 0x77afa1c5, 0x20756060,
0x85cbfe4e, 0x8ae88dd8, 0x7aaaf9b0, 0x4cf9aa7e,
0x1948c25c, 0x02fb8a8c, 0x01c36ae4, 0xd6ebe1f9,
0x90d4f869, 0xa65cdea0, 0x3f09252d, 0xc208e69f,
0xb74e6132, 0xce77e25b, 0x578fdfe3, 0x3ac372e6}
},
{
0x243f6a88, 0x85a308d3, 0x13198a2e, 0x03707344,
0xa4093822, 0x299f31d0, 0x082efa98, 0xec4e6c89,
0x452821e6, 0x38d01377, 0xbe5466cf, 0x34e90c6c,
0xc0ac29b7, 0xc97c50dd, 0x3f84d5b5, 0xb5470917,
0x9216d5d9, 0x8979fb1b
} };
*c = initstate;
}
u_int32_t
Blowfish_stream2word(const u_int8_t *data, u_int16_t databytes,
u_int16_t *current)
{
u_int8_t i;
u_int16_t j;
u_int32_t temp;
temp = 0x00000000;
j = *current;
for (i = 0; i < 4; i++, j++) {
if (j >= databytes)
j = 0;
temp = (temp << 8) | data[j];
}
*current = j;
return temp;
}
void
Blowfish_expand0state(blf_ctx *c, const u_int8_t *key, u_int16_t keybytes)
{
u_int16_t i;
u_int16_t j;
u_int16_t k;
u_int32_t temp;
u_int32_t datal;
u_int32_t datar;
j = 0;
for (i = 0; i < BLF_N + 2; i++) {
/* Extract 4 int8 to 1 int32 from keystream */
temp = Blowfish_stream2word(key, keybytes, &j);
c->P[i] = c->P[i] ^ temp;
}
j = 0;
datal = 0x00000000;
datar = 0x00000000;
for (i = 0; i < BLF_N + 2; i += 2) {
Blowfish_encipher(c, &datal, &datar);
c->P[i] = datal;
c->P[i + 1] = datar;
}
for (i = 0; i < 4; i++) {
for (k = 0; k < 256; k += 2) {
Blowfish_encipher(c, &datal, &datar);
c->S[i][k] = datal;
c->S[i][k + 1] = datar;
}
}
}
void
Blowfish_expandstate(blf_ctx *c, const u_int8_t *data, u_int16_t databytes,
const u_int8_t *key, u_int16_t keybytes)
{
u_int16_t i;
u_int16_t j;
u_int16_t k;
u_int32_t temp;
u_int32_t datal;
u_int32_t datar;
j = 0;
for (i = 0; i < BLF_N + 2; i++) {
/* Extract 4 int8 to 1 int32 from keystream */
temp = Blowfish_stream2word(key, keybytes, &j);
c->P[i] = c->P[i] ^ temp;
}
j = 0;
datal = 0x00000000;
datar = 0x00000000;
for (i = 0; i < BLF_N + 2; i += 2) {
datal ^= Blowfish_stream2word(data, databytes, &j);
datar ^= Blowfish_stream2word(data, databytes, &j);
Blowfish_encipher(c, &datal, &datar);
c->P[i] = datal;
c->P[i + 1] = datar;
}
for (i = 0; i < 4; i++) {
for (k = 0; k < 256; k += 2) {
datal ^= Blowfish_stream2word(data, databytes, &j);
datar ^= Blowfish_stream2word(data, databytes, &j);
Blowfish_encipher(c, &datal, &datar);
c->S[i][k] = datal;
c->S[i][k + 1] = datar;
}
}
}
void
blf_key(blf_ctx *c, const u_int8_t *k, u_int16_t len)
{
/* Initialize S-boxes and subkeys with Pi */
Blowfish_initstate(c);
/* Transform S-boxes and subkeys with key */
Blowfish_expand0state(c, k, len);
}
void
blf_enc(blf_ctx *c, u_int32_t *data, u_int16_t blocks)
{
u_int32_t *d;
u_int16_t i;
d = data;
for (i = 0; i < blocks; i++) {
Blowfish_encipher(c, d, d + 1);
d += 2;
}
}
void
blf_dec(blf_ctx *c, u_int32_t *data, u_int16_t blocks)
{
u_int32_t *d;
u_int16_t i;
d = data;
for (i = 0; i < blocks; i++) {
Blowfish_decipher(c, d, d + 1);
d += 2;
}
}
void
blf_ecb_encrypt(blf_ctx *c, u_int8_t *data, u_int32_t len)
{
u_int32_t l, r;
u_int32_t i;
for (i = 0; i < len; i += 8) {
l = data[0] << 24 | data[1] << 16 | data[2] << 8 | data[3];
r = data[4] << 24 | data[5] << 16 | data[6] << 8 | data[7];
Blowfish_encipher(c, &l, &r);
data[0] = l >> 24 & 0xff;
data[1] = l >> 16 & 0xff;
data[2] = l >> 8 & 0xff;
data[3] = l & 0xff;
data[4] = r >> 24 & 0xff;
data[5] = r >> 16 & 0xff;
data[6] = r >> 8 & 0xff;
data[7] = r & 0xff;
data += 8;
}
}
void
blf_ecb_decrypt(blf_ctx *c, u_int8_t *data, u_int32_t len)
{
u_int32_t l, r;
u_int32_t i;
for (i = 0; i < len; i += 8) {
l = data[0] << 24 | data[1] << 16 | data[2] << 8 | data[3];
r = data[4] << 24 | data[5] << 16 | data[6] << 8 | data[7];
Blowfish_decipher(c, &l, &r);
data[0] = l >> 24 & 0xff;
data[1] = l >> 16 & 0xff;
data[2] = l >> 8 & 0xff;
data[3] = l & 0xff;
data[4] = r >> 24 & 0xff;
data[5] = r >> 16 & 0xff;
data[6] = r >> 8 & 0xff;
data[7] = r & 0xff;
data += 8;
}
}
void
blf_cbc_encrypt(blf_ctx *c, u_int8_t *iv, u_int8_t *data, u_int32_t len)
{
u_int32_t l, r;
u_int32_t i, j;
for (i = 0; i < len; i += 8) {
for (j = 0; j < 8; j++)
data[j] ^= iv[j];
l = data[0] << 24 | data[1] << 16 | data[2] << 8 | data[3];
r = data[4] << 24 | data[5] << 16 | data[6] << 8 | data[7];
Blowfish_encipher(c, &l, &r);
data[0] = l >> 24 & 0xff;
data[1] = l >> 16 & 0xff;
data[2] = l >> 8 & 0xff;
data[3] = l & 0xff;
data[4] = r >> 24 & 0xff;
data[5] = r >> 16 & 0xff;
data[6] = r >> 8 & 0xff;
data[7] = r & 0xff;
iv = data;
data += 8;
}
}
void
blf_cbc_decrypt(blf_ctx *c, u_int8_t *iva, u_int8_t *data, u_int32_t len)
{
u_int32_t l, r;
u_int8_t *iv;
u_int32_t i, j;
iv = data + len - 16;
data = data + len - 8;
for (i = len - 8; i >= 8; i -= 8) {
l = data[0] << 24 | data[1] << 16 | data[2] << 8 | data[3];
r = data[4] << 24 | data[5] << 16 | data[6] << 8 | data[7];
Blowfish_decipher(c, &l, &r);
data[0] = l >> 24 & 0xff;
data[1] = l >> 16 & 0xff;
data[2] = l >> 8 & 0xff;
data[3] = l & 0xff;
data[4] = r >> 24 & 0xff;
data[5] = r >> 16 & 0xff;
data[6] = r >> 8 & 0xff;
data[7] = r & 0xff;
for (j = 0; j < 8; j++)
data[j] ^= iv[j];
iv -= 8;
data -= 8;
}
l = data[0] << 24 | data[1] << 16 | data[2] << 8 | data[3];
r = data[4] << 24 | data[5] << 16 | data[6] << 8 | data[7];
Blowfish_decipher(c, &l, &r);
data[0] = l >> 24 & 0xff;
data[1] = l >> 16 & 0xff;
data[2] = l >> 8 & 0xff;
data[3] = l & 0xff;
data[4] = r >> 24 & 0xff;
data[5] = r >> 16 & 0xff;
data[6] = r >> 8 & 0xff;
data[7] = r & 0xff;
for (j = 0; j < 8; j++)
data[j] ^= iva[j];
}
#if 0
void
report(u_int32_t data[], u_int16_t len)
{
u_int16_t i;
for (i = 0; i < len; i += 2)
printf("Block %0hd: %08lx %08lx.\n",
i / 2, data[i], data[i + 1]);
}
void
main(void)
{
blf_ctx c;
char key[] = "AAAAA";
char key2[] = "abcdefghijklmnopqrstuvwxyz";
u_int32_t data[10];
u_int32_t data2[] =
{0x424c4f57l, 0x46495348l};
u_int16_t i;
/* First test */
for (i = 0; i < 10; i++)
data[i] = i;
blf_key(&c, (u_int8_t *) key, 5);
blf_enc(&c, data, 5);
blf_dec(&c, data, 1);
blf_dec(&c, data + 2, 4);
printf("Should read as 0 - 9.\n");
report(data, 10);
/* Second test */
blf_key(&c, (u_int8_t *) key2, strlen(key2));
blf_enc(&c, data2, 1);
printf("\nShould read as: 0x324ed0fe 0xf413a203.\n");
report(data2, 2);
blf_dec(&c, data2, 1);
report(data2, 2);
}
#endif

99
staging/spec/fixtures/apps/node_native_dependencies/source/node_modules/bcrypt/src/node_blf.h сгенерированный поставляемый Executable file
Просмотреть файл

@ -0,0 +1,99 @@
/* $OpenBSD: blf.h,v 1.7 2007/03/14 17:59:41 grunk Exp $ */
/*
* Blowfish - a fast block cipher designed by Bruce Schneier
*
* Copyright 1997 Niels Provos <provos@physnet.uni-hamburg.de>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by Niels Provos.
* 4. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef _NODE_BLF_H_
#define _NODE_BLF_H_
/* Solaris compatibility */
#ifdef __sun
#define u_int8_t uint8_t
#define u_int16_t uint16_t
#define u_int32_t uint32_t
#define u_int64_t uint64_t
#endif
/* Schneier specifies a maximum key length of 56 bytes.
* This ensures that every key bit affects every cipher
* bit. However, the subkeys can hold up to 72 bytes.
* Warning: For normal blowfish encryption only 56 bytes
* of the key affect all cipherbits.
*/
#define BLF_N 16 /* Number of Subkeys */
#define BLF_MAXKEYLEN ((BLF_N-2)*4) /* 448 bits */
#define BLF_MAXUTILIZED ((BLF_N+2)*4) /* 576 bits */
#define _PASSWORD_LEN 128 /* max length, not counting NUL */
#define _SALT_LEN 32 /* max length */
/* Blowfish context */
typedef struct BlowfishContext {
u_int32_t S[4][256]; /* S-Boxes */
u_int32_t P[BLF_N + 2]; /* Subkeys */
} blf_ctx;
/* Raw access to customized Blowfish
* blf_key is just:
* Blowfish_initstate( state )
* Blowfish_expand0state( state, key, keylen )
*/
void Blowfish_encipher(blf_ctx *, u_int32_t *, u_int32_t *);
void Blowfish_decipher(blf_ctx *, u_int32_t *, u_int32_t *);
void Blowfish_initstate(blf_ctx *);
void Blowfish_expand0state(blf_ctx *, const u_int8_t *, u_int16_t);
void Blowfish_expandstate
(blf_ctx *, const u_int8_t *, u_int16_t, const u_int8_t *, u_int16_t);
/* Standard Blowfish */
void blf_key(blf_ctx *, const u_int8_t *, u_int16_t);
void blf_enc(blf_ctx *, u_int32_t *, u_int16_t);
void blf_dec(blf_ctx *, u_int32_t *, u_int16_t);
void blf_ecb_encrypt(blf_ctx *, u_int8_t *, u_int32_t);
void blf_ecb_decrypt(blf_ctx *, u_int8_t *, u_int32_t);
void blf_cbc_encrypt(blf_ctx *, u_int8_t *, u_int8_t *, u_int32_t);
void blf_cbc_decrypt(blf_ctx *, u_int8_t *, u_int8_t *, u_int32_t);
/* Converts u_int8_t to u_int32_t */
u_int32_t Blowfish_stream2word(const u_int8_t *, u_int16_t , u_int16_t *);
/* bcrypt functions*/
void bcrypt_gensalt(u_int8_t, u_int8_t*, char *);
void bcrypt(const char *, const char *, char *);
void encode_salt(char *, u_int8_t *, u_int16_t, u_int8_t);
u_int32_t bcrypt_get_rounds(const char *);
#endif

56
staging/spec/fixtures/apps/node_native_dependencies/source/node_modules/bcrypt/wscript сгенерированный поставляемый Executable file
Просмотреть файл

@ -0,0 +1,56 @@
# -*- mode: python -*-
import Options, Utils, sys
from os import unlink, symlink, popen
from os.path import exists, islink
srcdir = "."
blddir = "build"
VERSION = "0.0.1"
def set_options(opt):
opt.tool_options("compiler_cxx")
opt.tool_options("compiler_cc")
def configure(conf):
conf.check_tool("compiler_cxx")
conf.check_tool("compiler_cc")
conf.check_tool("node_addon")
o = Options.options
libpath = ['/lib', '/usr/lib', '/usr/local/lib', '/opt/local/lib', '/usr/sfw/lib']
includes = ['/usr/include', '/usr/includes', '/usr/local/includes', '/opt/local/includes', '/usr/sfw/lib'];
libssl = conf.check(lib="ssl",
header_name='openssl/rand.h',
function_name='RAND_bytes',
includes=includes,
libpath=libpath,
uselib_store='OPENSSL')
if sys.platform == "cygwin":
libcrypto = conf.check(lib="crypto",
includes=includes,
libpath=libpath,
uselib_store='CRYPTO')
libz = conf.check(lib="z",
includes=includes,
libpath=libpath,
uselib_store='Z')
def build(bld):
bcryptnode = bld.new_task_gen("cxx", "shlib", "node_addon")
#bcryptnode.cxxflags = [ "-g" ] #debugging.
bcryptnode.target = "bcrypt_lib"
bcryptnode.source = """
src/blowfish.cc
src/bcrypt.cc
src/bcrypt_node.cc
"""
uselib = "OPENSSL"
if sys.platform == "cygwin":
uselib += " CRYPTO Z"
bcryptnode.uselib = uselib
def test(t):
Utils.exec_command('make test')

Просмотреть файл

@ -0,0 +1,7 @@
{
"name" : "node_native_dependecies",
"version": "0.1.0",
"dependencies" : {
"bcrypt" : "" // to test native dependencies
}
}

Просмотреть файл

@ -1,4 +1,4 @@
require 'spec_helper'
require "spec_helper"
describe "A simple Node.js app being staged" do
before do
@ -7,7 +7,7 @@ describe "A simple Node.js app being staged" do
it "is packaged with a startup script" do
stage :node do |staged_dir|
start_script = File.join(staged_dir, 'startup')
start_script = File.join(staged_dir, "startup")
start_script.should be_executable_file
script_body = File.read(start_script)
script_body.should == <<-EXPECTED
@ -28,7 +28,7 @@ EXPECTED
it "uses it for the start command" do
stage :node do |staged_dir|
start_script = File.join(staged_dir, 'startup')
start_script = File.join(staged_dir, "startup")
start_script.should be_executable_file
script_body = File.read(start_script)
script_body.should == <<-EXPECTED
@ -50,7 +50,7 @@ EXPECTED
it "uses it for the start command with executable prepended" do
stage :node do |staged_dir|
start_script = File.join(staged_dir, 'startup')
start_script = File.join(staged_dir, "startup")
start_script.should be_executable_file
script_body = File.read(start_script)
script_body.should == <<-EXPECTED
@ -73,7 +73,7 @@ EXPECTED
it "fails and lets the exception propagate" do
proc {
stage :node do |staged_dir|
start_script = File.join(staged_dir, 'startup')
start_script = File.join(staged_dir, "startup")
start_script.should be_executable_file
script_body = File.read(start_script)
script_body.should == <<-EXPECTED
@ -110,5 +110,35 @@ EXPECTED
end
end
end
describe "with a package.json that defines dependencies" do
before do
app_fixture :node_dependencies
end
it "installs required node modules" do
pending "untill npm is available during test run"
stage :node do |staged_dir|
package_dir = File.join(staged_dir, "app", "node_modules", "express")
File.exist?(package_dir).should be_true
end
end
end
describe "with a native dependencies" do
before do
app_fixture :node_native_dependencies
end
it "rebuilds required node modules" do
pending "untill npm is available during test run"
stage :node do |staged_dir|
package_dir = File.join(staged_dir, "app", "node_modules", "bcrypt")
built_package = File.join(package_dir, "build", "Release", "bcrypt_lib.node")
File.exist?(built_package).should be_true
end
end
end
end