hades-krb5
Version:
Kerberos library for Node.js forked to fix some C++ issues
115 lines (105 loc) • 4.31 kB
text/coffeescript
fs = require 'fs'
krb5 = require('bindings')('krb5')
module.exports = (options, callback) ->
k = new Krb5 options
if callback
k.kinit (err) -> callback err, k
k
module.exports.spnego = (options, callback) ->
return callback new Error 'Params: Not an object' unless typeof options is 'object'
return callback new Error 'Params: Please set principal property' unless options.principal?
return callback new Error 'Params: principal is unvalid, please use ID@REALM' unless options.principal.match /[A-Za-z0-9_\-\/]*@[A-Za-z0-9_\-\.]*/
return callback new Error 'Params: please set service_principal property' unless options.service_principal?
return callback new Error 'Params: service_principal is unvalid, please use ID@REALM' unless options.service_principal.match /[A-Za-z0-9_\-\/]*@[A-Za-z0-9_\-\.]*/
k = new Krb5 options
k.kinit (err) ->
return callback err if err
k.token options.service_principal, callback
k
###
Options includes:
* `principal`
* `password`
* `keytab`
* `service_principal`
* `service_fqdn`
* `ccname`
###
Krb5 = module.exports.Krb5 = () ->
= new krb5.Krb5
@
Krb5::kinitSync = () ->
if .ccname?.indexOf(':') is -1
stat = fs.statSync .ccname
if stat.isFile()
.ccname =+ "FILE:"
else if stat.isDirectory()
.ccname =+ "DIR:"
else return throw Error 'Invalid Option "ccname"'
throw Error 'principal not set' unless .principal?
[user, realm] = .principal.split '@'
if .ccname?
process.env.KRB5CCNAME = .ccname
.initSync user, realm, .ccname.split(':')[1]
else
.initSync user, realm
if .password?
.getCredentialsByPasswordSync .password
else if .keytab?
.getCredentialsByKeytabSync .keytab
else
.getCredentialsByKeytabSync
Krb5::kinit = (callback) ->
return callback Error 'Missing Property "principal"' unless .principal?
do_ccname = =>
return do_kinit() if not .ccname or .ccname.indexOf(':') isnt -1
fs.stat .ccname, (err, stat) ->
if stat.isFile()
.ccname =+ "FILE:"
else if stat.isDirectory()
.ccname =+ "DIR:"
else return callback Error 'Invalid Option "ccname"'
process.env.KRB5CCNAME = .ccname if .ccname
do_kinit()
do_kinit = =>
[user, realm] = .principal.split '@'
.init user, realm, ((err) -> if err then callback err else do_credential())
do_credential = =>
if .password?
method = 'getCredentialsByPassword'
param = .password
else if .keytab?
method = 'getCredentialsByKeytab'
param = .keytab
else
callback Error 'Invalid arguments'
[method] param, callback
do_ccname()
Krb5::kdestroySync = (cache) ->
return if cache? then .destroySync cache else .destroySync()
Krb5::kdestroy = (cache, callback) ->
if typeof cache is 'function'
callback = cache
cache = null
if cache? then .destroy cache, callback else .destroy callback
Krb5::tokenSync = (service_principal_or_fqdn) ->
service_principal_or_fqdn ?= .service_principal
service_principal_or_fqdn ?= .service_fqdn
throw Error 'Missing property "service_principal" or "service_fqdn"' unless service_principal_or_fqdn
service_principal_or_fqdn = "HTTP@#{service_principal_or_fqdn}" unless /HTTP[@\/]/.test service_principal_or_fqdn
.generateSpnegoTokenSync service_principal_or_fqdn
Krb5::token = (service_principal_or_fqdn, callback) ->
if arguments.length is 1
callback = service_principal_or_fqdn
service_principal_or_fqdn = null
ts = Date.now()
if is ts
return setTimeout =>
service_principal_or_fqdn, callback
, 1
= ts
service_principal_or_fqdn ?= .service_principal
service_principal_or_fqdn ?= .service_fqdn
return callback Error 'Missing property "service_principal" or "service_fqdn"' unless service_principal_or_fqdn
service_principal_or_fqdn = "HTTP@#{service_principal_or_fqdn}" unless /HTTP[@\/]/.test service_principal_or_fqdn
.generateSpnegoToken service_principal_or_fqdn, callback