# -*- coding: utf-8 -*-
#
# LinOTP - the open source solution for two factor authentication
# Copyright (C) 2010 - 2014 LSE Leading Security Experts GmbH
#
# This file is part of LinOTP server.
#
# This program is free software: you can redistribute it and/or
# modify it under the terms of the GNU Affero General Public
# License, version 3, as published by the Free Software Foundation.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the
# GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
#
# E-mail: linotp@lsexperts.de
# Contact: www.linotp.org
# Support: www.lsexperts.de
#
"""
admin controller - interfaces to administrate LinOTP
"""
import logging
from pylons import request, response, config, tmpl_context as c
from linotp.lib.base import BaseController
from linotp.lib.token import enableToken, assignToken , unassignToken, removeToken
from linotp.lib.token import setPin, setMaxFailCount, setOtpLen, setSyncWindow, setCounterWindow
from linotp.lib.token import setDescription
from linotp.lib.token import resyncToken, resetToken, setPinUser, setPinSo, setHashLib, addTokenInfo
from linotp.lib.token import TokenIterator, initToken, setRealms, getTokenType, get_serial_by_otp
from linotp.lib.token import getTokens4UserOrSerial, copyTokenPin, copyTokenUser, losttoken, check_serial
from linotp.lib.token import genSerial
from linotp.lib.token import newToken
from linotp.lib.error import ParameterError
from linotp.lib.util import getParam, getLowerParams
from linotp.lib.util import check_session, SESSION_KEY_LENGTH, remove_session_from_param
from linotp.lib.util import get_client
from linotp.lib.user import getSearchFields, getUserList, User, getUserFromParam, getUserFromRequest
from linotp.lib.realm import getDefaultRealm
from linotp.lib.reply import sendResult, sendError, sendXMLResult, sendXMLError, sendCSVResult
from linotp.lib.reply import sendQRImageResult
from linotp.lib.validate import get_challenges
from linotp.model.meta import Session
from linotp.lib.policy import checkPolicyPre, checkPolicyPost, PolicyException, getAdminPolicies, getOTPPINEncrypt
from linotp.lib.audit.base import logTokenNum
# for loading XML file
from linotp.lib.ImportOTP import parseSafeNetXML, parseOATHcsv, ImportException, parseYubicoCSV
from tempfile import mkstemp
import os
import traceback
# For logout
from webob.exc import HTTPUnauthorized
audit = config.get('audit')
log = logging.getLogger(__name__)
optional = True
required = False
[docs]class AdminController(BaseController):
'''
The linotp.controllers are the implementation of the web-API to talk to the LinOTP server.
The AdminController is used for administrative tasks like adding tokens to LinOTP,
assigning tokens or revoking tokens.
The functions of the AdminController are invoked like this
https://server/admin/<functionname>
The functions are described below in more detail.
'''
def __before__(self, action, **params):
'''
'''
try:
log.debug("[__before__::%r] %r" % (action, params))
audit.initialize()
c.audit['success'] = False
c.audit['client'] = get_client()
self.set_language()
# Session handling
check_session()
Session.commit()
return request
except Exception as exx:
log.error("[__before__::%r] exception %r" % (action, exx))
log.error("[__before__] %s" % traceback.format_exc())
Session.rollback()
Session.close()
return sendError(response, exx, context='before')
finally:
log.debug("[__before__::%r] done" % (action))
def __after__(self):
'''
'''
params = {}
try:
params.update(request.params)
c.audit['administrator'] = getUserFromRequest(request).get("login")
if 'serial' in params:
c.audit['serial'] = request.params['serial']
c.audit['token_type'] = getTokenType(params.get('serial'))
audit.log(c.audit)
Session.commit()
return request
except Exception as e:
log.error("[__after__] unable to create a session cookie: %r" % e)
log.error("[__after__] %s" % traceback.format_exc())
Session.rollback()
return sendError(response, e, context='after')
finally:
Session.close()
log.debug("[__after__] done")
def logout(self):
# see http://docs.pylonsproject.org/projects/pyramid/1.0/narr/webob.html
c.audit['action_detail'] = "logout"
#response.status = "401 Not authenticated"
nonce = request.environ.get("nonce")
realm = request.environ.get("realm")
detail = "401 Unauthorized"
#return HTTPUnauthorized(request=request)
raise HTTPUnauthorized(
unicode(detail),
[('WWW-Authenticate', 'Digest realm="%s", nonce="%s", qop="auth"' % (realm, nonce))]
)
#raise exc.HTTPUnauthorized(
# str(detail),
# [('WWW-Authenticate', 'Basic realm="%s"' % realm)]
# )
#abort(401, "You are not authenticated")
[docs] def getsession(self):
'''
This generates a session key and sets it as a cookie
set_cookie is defined in python-webob::
def set_cookie(self, key, value='', max_age=None,
path='/', domain=None, secure=None, httponly=False,
version=None, comment=None, expires=None, overwrite=False):
'''
import binascii
try:
web_host = request.environ.get('HTTP_HOST')
# HTTP_HOST also contains the port number. We need to stript this!
web_host = web_host.split(':')[0]
log.debug("[getsession] environment: %s" % request.environ)
log.debug("[getsession] found this web_host: %s" % web_host)
random_key = os.urandom(SESSION_KEY_LENGTH)
cookie = binascii.hexlify(random_key)
log.debug("[getsession] adding session cookie %s to response." % cookie)
# we send all three to cope with IE8
response.set_cookie('admin_session', value=cookie, domain=web_host)
# this produces an error with the gtk client
# response.set_cookie('admin_session', value=cookie, domain=".%" % web_host )
response.set_cookie('admin_session', value=cookie, domain="")
return sendResult(response, True)
except Exception as e:
log.error("[getsession] unable to create a session cookie: %r" % e)
log.error("[getsession] %s" % traceback.format_exc())
Session.rollback()
return sendError(response, e)
finally:
Session.close()
log.debug("[getsession] done")
def dropsession(self):
#request.cookies.pop( 'admin_session', None )
# FIXME: Does not seem to work
response.set_cookie('admin_session', None, expires=1)
return
[docs] def show(self):
"""
method:
admin/show
description:
displays the list of the available tokens
arguments:
* serial - optional: only this serial will be displayed
* user - optional: only the tokens of this user will be displayed. If the user does not exist,
linotp will search tokens of users, who contain this substring.
**TODO:** This can be very time consuming an will be changed in the next release to use wildcards.
* filter - optional: takes a substring to search in table token columns
* viewrealm - optional: takes a realm, only the tokens in this realm will be displayed
* sortby - optional: sort the output by column
* sortdir - optional: asc/desc
* page - optional: reqeuest a certain page
* pagesize- optional: limit the number of returned tokens
* user_fields - optional: additional user fields from the userid resolver of the owner (user)
* outform - optional: if set to "csv", than the token list will be given in CSV
returns:
a json result with:
{ "head": [],
"data": [ [row1], [row2] .. ]
}
exception:
if an error occurs an exception is serialized and returned
"""
param = request.params
try:
serial = getParam(param, "serial", optional)
page = getParam(param, "page", optional)
filter = getParam(param, "filter", optional)
sort = getParam(param, "sortby", optional)
dir = getParam(param, "sortdir", optional)
psize = getParam(param, "pagesize", optional)
realm = getParam(param, "viewrealm", optional)
ufields = getParam(param, "user_fields", optional)
output_format = getParam(param, "outform", optional)
user_fields = []
if ufields:
user_fields = [u.strip() for u in ufields.split(",")]
user = getUserFromParam(param, optional)
filterRealm = []
# check admin authorization
res = checkPolicyPre('admin', 'show', param , user=user)
filterRealm = res['realms']
# check if policies are active at all
# If they are not active, we are allowed to SHOW any tokens.
pol = getAdminPolicies("show")
# If there are no admin policies, we are allowed to see all realms
if not pol['active']:
filterRealm = ["*"]
# If the admin wants to see only one realm, then do it:
log.debug("[show] checking to only see tokens in realm <%s>" % realm)
if realm:
if realm in filterRealm or '*' in filterRealm:
filterRealm = [realm]
log.info("[show] admin >%s< may display the following realms: %s" % (res['admin'], filterRealm))
log.info("[show] displaying tokens: serial: %s, page: %s, filter: %s, user: %s", serial, page, filter, user.login)
toks = TokenIterator(user, serial, page, psize, filter, sort, dir, filterRealm, user_fields)
c.audit['success'] = True
c.audit['info'] = "realm: %s, filter: %r" % (filterRealm, filter)
# put in the result
result = {}
# now row by row
lines = []
for tok in toks:
# CKO:
log.debug("tokenline: %s" % tok)
lines.append(tok)
result["data"] = lines
result["resultset"] = toks.getResultSetInfo()
Session.commit()
if output_format == "csv":
return sendCSVResult(response, result)
else:
return sendResult(response, result)
except PolicyException as pe:
log.error('[show] policy failed: %r' % pe)
log.error("[show] %s" % traceback.format_exc())
Session.rollback()
return sendError(response, unicode(pe), 1)
except Exception as e:
log.error('[show] failed: %r' % e)
log.error("[show] %s" % traceback.format_exc())
Session.rollback()
return sendError(response, e)
finally:
Session.close()
log.debug("[show] done")
########################################################
[docs] def remove(self):
"""
method:
admin/remove
description:
deletes either a certain token given by serial or all tokens of a user
arguments:
* serial - optional
* user - optional
returns:
a json result with a boolean
"result": true
exception:
if an error occurs an exception is serialized and returned
"""
log.debug("[remove] calling remove ")
param = request.params
try:
serial = getParam(param, "serial", optional)
user = getUserFromParam(param, optional)
# check admin authorization
checkPolicyPre('admin', 'remove', param)
log.info("[remove] removing token with serial %s for user %s", serial, user.login)
ret = removeToken(user, serial)
c.audit['user'] = user.login
c.audit['realm'] = user.realm
if "" == c.audit['realm'] and "" != c.audit['user']:
c.audit['realm'] = getDefaultRealm()
logTokenNum()
c.audit['success'] = ret
Session.commit()
return sendResult(response, ret)
except PolicyException as pe:
log.error("[remove] policy failed %r" % pe)
log.error("[remove] %s" % traceback.format_exc())
Session.rollback()
return sendError(response, unicode(pe), 1)
except Exception as e:
log.error("[remove] failed! %r" % e)
log.error("[remove] %s" % traceback.format_exc())
Session.rollback()
return sendError(response, e)
finally:
Session.close()
log.debug('[remove] done')
########################################################
[docs] def enable (self):
"""
method:
admin/enable
description:
enables a token or all tokens of a user
arguments:
* serial - optional
* user - optional
returns:
a json result with a boolean
"result": true
exception:
if an error occurs an exception is serialized and returned
"""
log.debug("[enable] calling enable to enable/disable a token")
param = request.params
try:
serial = getParam(param, "serial", optional)
user = getUserFromParam(param, optional)
# check admin authorization
checkPolicyPre('admin', 'enable', param , user=user)
log.info("[enable] enable token with serial %s for user %s@%s.", serial, user.login, user.realm)
ret = enableToken(True, user, serial)
c.audit['success'] = ret
c.audit['user'] = user.login
c.audit['realm'] = user.realm
logTokenNum()
if "" == c.audit['realm'] and "" != c.audit['user']:
c.audit['realm'] = getDefaultRealm()
Session.commit()
return sendResult(response, ret, 1)
except PolicyException as pe:
log.error("[enable] policy failed %r" % pe)
log.error("[enable] %s" % traceback.format_exc())
Session.rollback()
return sendError(response, unicode(pe), 1)
except Exception as e:
log.error("[enable] failed: %r" % e)
log.error("[enable] %s" % traceback.format_exc())
Session.rollback()
log.error('[enable] error enabling token')
return sendError(response, e, 1)
finally:
Session.close()
log.debug('[enable] done')
########################################################
[docs] def getSerialByOtp (self):
"""
method:
admin/getSerialByOtp
description:
searches for the token, that generates the given OTP value.
The search can be restricted by several critterions
arguments:
* otp - required. Will search for the token, that produces this OTP value
* type - optional, will only search in tokens of type
* realm - optional, only search in this realm
* assigned - optional. 1: only search assigned tokens, 0: only search unassigned tokens
returns:
a json result with the serial
exception:
if an error occurs an exception is serialized and returned
"""
log.debug("[getSerialByOtp] entering function")
ret = {}
param = request.params
try:
otp = getParam(param, "otp", required)
typ = getParam(param, "type", optional)
realm = getParam(param, "realm", optional)
assigned = getParam(param, "assigned", optional)
serial = ""
username = ""
# check admin authorization
checkPolicyPre('admin', 'getserial', param)
serial, username, resolverClass = get_serial_by_otp(None, otp, 10, typ=typ, realm=realm, assigned=assigned)
log.debug("[getSerialByOtp] found %s with user %s" % (serial, username))
if "" != serial:
checkPolicyPost('admin', 'getserial', {'serial' : serial})
c.audit['success'] = 1
c.audit['serial'] = serial
ret['success'] = True
ret['serial'] = serial
ret['user_login'] = username
ret['user_resolver'] = resolverClass
Session.commit()
return sendResult(response, ret, 1)
except PolicyException as pe:
log.error("[disable] policy failed %r" % pe)
log.error("[disable] %s" % traceback.format_exc())
Session.rollback()
return sendError(response, unicode(pe), 1)
except Exception as e:
c.audit['success'] = 0
Session.rollback()
log.error('[getSerialByOtp] error: %r' % e)
log.error("[getSerialByOtp] %s" % traceback.format_exc())
return sendError(response, e, 1)
finally:
Session.close()
log.debug("[getSerialByOtp] done")
########################################################
[docs] def disable (self):
"""
method:
admin/disable
description:
disables a token given by serial or all tokens of a user
arguments:
* serial - optional
* user - optional
returns:
a json result with a boolean
"result": true
exception:
if an error occurs an exception is serialized and returned
"""
log.debug("calling enable to enable/disable a token")
param = request.params
try:
serial = getParam(param, "serial", optional)
user = getUserFromParam(param, optional)
# check admin authorization
checkPolicyPre('admin', 'disable', param, user=user)
log.info("[disable] disable token with serial %s for user %s@%s.", serial, user.login, user.realm)
ret = enableToken(False, user, serial)
c.audit['success'] = ret
c.audit['user'] = user.login
c.audit['realm'] = user.realm
if "" == c.audit['realm'] and "" != c.audit['user']:
c.audit['realm'] = getDefaultRealm()
Session.commit()
return sendResult(response, ret, 1)
except PolicyException as pe:
log.error("[disable] policy failed %r" % pe)
log.error("[disable] %s" % traceback.format_exc())
Session.rollback()
return sendError(response, unicode(pe), 1)
except Exception as e:
log.error("[disable] failed! %r" % e)
log.error("[disable] %s" % traceback.format_exc())
Session.rollback()
return sendError(response, e, 1)
finally:
Session.close()
log.debug('[disable] done')
#######################################################
[docs] def check_serial(self):
'''
method
admin/check_serial
description:
This function checks, if a given serial will be unique.
It returns True if the serial does not yet exist and
new_serial as a new value for a serial, that does not exist, yet
arguments:
serial - required- the serial to be checked
returns:
a json result with a new suggestion for the serial
exception:
if an error occurs an exception is serialized and returned
'''
log.debug("calling check_serial")
param = request.params
try:
serial = getParam(param, "serial", required)
# check admin authorization
#try:
# checkPolicyPre('admin', 'disable', param )
#except PolicyException as pe:
# return sendError(response, str(pe), 1)
log.info("[check_serial] checking serial %s" % serial)
(unique, new_serial) = check_serial(serial)
c.audit['success'] = True
c.audit['serial'] = serial
c.audit['action_detail'] = "%r - %r" % (unique, new_serial)
Session.commit()
return sendResult(response, {"unique":unique, "new_serial":new_serial}, 1)
except PolicyException as pe:
log.error("[check_serial] policy failed %r" % pe)
log.error("[check_serial] %s" % traceback.format_exc())
Session.rollback()
return sendError(response, unicode(pe), 1)
except Exception as e:
log.error("[check_serial] failed! %r" % e)
log.error("[check_serial] %s" % traceback.format_exc())
Session.rollback()
return sendError(response, e)
finally:
Session.close()
log.debug("[check_serial] done")
########################################################
[docs] def init(self):
"""
method:
admin/init
description:
creates a new token.
arguments:
* otpkey - required - the hmac Key of the token
* genkey - required - =1, if key should be generated. We either need otpkey or genkey
* keysize - optional - either 20 or 32. Default is 20
* serial - required - the serial number / identifier of the token
* description - optional
* pin - optional - the pin of the user pass
* user - optional - login user name
* realm - optional - realm of the user
* type - optional - the type of the token
* tokenrealm - optional - the realm a token should be put into
* otplen - optional - length of the OTP value
* hashlib - optional - used hashlib sha1 oder sha256
ocra arguments:
for generating OCRA Tokens type=ocra you can specify the following parameters:
* ocrasuite - optional - if you do not want to use the default ocra suite OCRA-1:HOTP-SHA256-8:QA64
* sharedsecret - optional - if you are in Step0 of enrolling an OCRA/QR token the
sharedsecret=1 specifies,
that you want to generate a shared secret
* activationcode - optional - if you are in Step1 of enrolling an OCRA token you need to pass the
activation code, that was generated in the QRTAN-App
returns:
a json result with a boolean
"result": true
exception:
if an error occurs an exception is serialized and returned
"""
log.debug("[init] calling the init controller function")
ret = False
response_detail = {}
helper_param = {}
try:
tokenrealm = None
param = request.params
helper_param.update(param)
user = getUserFromParam(param, optional)
# check admin authorization
res = checkPolicyPre('admin', 'init', param, user=user)
if user is not None:
helper_param['user.login'] = user.login
helper_param['user.realm'] = user.realm
## for genkey, we have to transfer this to the lowest level
key_size = getParam(param, "keysize", optional) or 20
helper_param['key_size'] = key_size
tok_type = getParam(param, "type", optional) or 'hmac'
# if no user is given, we put the token in all realms of the admin
if user.login == "":
log.debug("[init] setting tokenrealm %s" % res['realms'])
tokenrealm = res['realms']
## look for the tokenclass to support a class init
## the classInit could do a rewrite of the request parameters
## which are then used in the tokenInit as parameters
## this is for example
## to find all open init challenges of a token type and set the
## serial number in the parameter list
g = config['pylons.app_globals']
tokenclasses = g.tokenclasses
tokenTypes = tokenclasses.keys()
if tok_type in tokenTypes:
tclass = tokenclasses.get(tok_type)
tclass_object = newToken(tclass)
if hasattr(tclass_object, 'classInit'):
h_params = tclass_object.classInit(param, user=user)
helper_param.update(h_params)
serial = helper_param.get('serial', None)
prefix = helper_param.get('prefix', None)
if serial is None or len(serial) == 0:
serial = genSerial(tok_type, prefix)
helper_param['serial'] = serial
log.info("[init] initialize token. user: %s, serial: %s" % (user.login, serial))
(ret, tokenObj) = initToken(helper_param, user, tokenrealm=tokenrealm)
## result enrichment - if the token is sucessfully created,
## some processing info is added to the result document,
## e.g. the otpkey :-) as qr code
initDetail = tokenObj.getInitDetail(helper_param, user)
response_detail.update(initDetail)
c.audit['success'] = ret
c.audit['user'] = user.login
c.audit['realm'] = user.realm
# DeleteMe: This code will never run, since getUserFromParam
# always returns a realm!
#if "" == c.audit['realm'] and "" != c.audit['user']:
# c.audit['realm'] = getDefaultRealm()
logTokenNum()
c.audit['success'] = ret
checkPolicyPost('admin', 'init', param, user=user)
Session.commit()
## finally we render the info as qr immage, if the qr parameter
## is provided and if the token supports this
if 'qr' in param and tokenObj is not None:
(rdata, hparam) = tokenObj.getQRImageData(response_detail)
hparam.update(response_detail)
hparam['qr'] = param.get('qr') or 'html'
return sendQRImageResult(response, rdata, hparam)
else:
return sendResult(response, ret, opt=response_detail)
except PolicyException as pe:
log.error("[init] policy failed %r" % pe)
log.error("[init] %s" % traceback.format_exc())
Session.rollback()
return sendError(response, unicode(pe), 1)
except Exception as e:
log.error("[init] token initialization failed! %r" % e)
log.error("[init] %s" % traceback.format_exc())
Session.rollback()
return sendError(response, e)
finally:
Session.close()
log.debug('[init] done')
########################################################
[docs] def unassign(self):
"""
method:
admin/unassign - remove the assigned user from the token
description:
unassigns a token from a user. i.e. the binding between the token
and the user is removed
arguments:
* serial - required - the serial number / identifier of the token
* user - optional
returns:
a json result with a boolean
"result": true
exception:
if an error occurs an exception is serialized and returned
"""
log.debug("[unassign] entering function unassign")
param = request.params
try:
serial = getParam(param, "serial", required)
user = getUserFromParam(param, optional)
log.debug("[unassign] unassigning serial %r, user %r" % (serial, user))
# check admin authorization
checkPolicyPre('admin', 'unassign', param)
log.info("[unassign] unassigning token with serial %r from "
"user %r@%r" % (serial, user.login, user.realm))
res = unassignToken(serial, user, None)
c.audit['success'] = res
c.audit['user'] = user.login
c.audit['realm'] = user.realm
if "" == c.audit['realm']:
c.audit['realm'] = getDefaultRealm()
Session.commit()
return sendResult(response, res, 1)
except PolicyException as pe:
log.error('[unassign] policy failed %r' % pe)
log.error("[unassign] %s" % traceback.format_exc())
Session.rollback()
return sendError(response, unicode(pe), 1)
except Exception as e:
log.error("[unassign] failed! %r" % e)
log.error("[unassign] %s" % traceback.format_exc())
Session.rollback()
return sendError(response, e, 1)
finally:
Session.close()
log.debug('[unassign] done')
########################################################
[docs] def assign(self):
"""
method:
admin/assign
description:
assigns a token to a user, i.e. a binding between the token and
the user is created.
arguments:
* serial - required - the serial number / identifier of the token
* user - required - login user name
* pin - optional - the pin of the user pass
returns:
a json result with a boolean
"result": true
exception:
if an error occurs an exception is serialized and returned
"""
log.debug("[assign] entering function assign")
param = request.params
try:
upin = getParam(param, "pin", optional)
serial = getParam(param, "serial", optional)
user = getUserFromParam(param, optional)
# check admin authorization
checkPolicyPre('admin', 'assign', param)
log.info("[assign] assigning token with serial %s to user %s@%s" % (serial, user.login, user.realm))
res = assignToken(serial, user, upin, param)
c.audit['success'] = res
c.audit['user'] = user.login
c.audit['realm'] = user.realm
if "" == c.audit['realm']:
c.audit['realm'] = getDefaultRealm()
Session.commit()
return sendResult(response, res, 1)
except PolicyException as pe:
log.error('[assign] policy failed %r' % pe)
log.error("[assign] %s" % traceback.format_exc())
Session.rollback()
return sendError(response, unicode(pe), 1)
except Exception as e :
log.error('[assign] token assignment failed! %r' % e)
log.error("[assign] %s" % traceback.format_exc())
Session.rollback()
return sendError(response, e, 0)
finally:
Session.close()
log.debug('[setPin] done')
########################################################
[docs] def setPin(self):
"""
method:
admin/set
description:
This function sets the smartcard PINs of a eTokenNG OTP.
The userpin is used to store the mOTP PIN of mOTP tokens!
!!! For setting the OTP PIN, use the function /admin/set!
arguments:
* serial - required
* userpin - optional: store the userpin
* sopin - optional: store the sopin
returns:
a json result with a boolean
"result": true
exception:
if an error occurs an exception is serialized and returned
"""
res = {}
count = 0
description = "setPin: parameters are\
serial\
userpin\
sopin\
"
log.debug('[setPin]')
try:
param = getLowerParams(request.params)
## if there is a pin
if param.has_key("userpin"):
msg = "setting userPin failed"
userPin = getParam(param, "userpin", required)
serial = getParam(param, "serial", required)
# check admin authorization
checkPolicyPre('admin', 'setPin', param)
log.info("[setPin] setting userPin for token with serial %s" % serial)
ret = setPinUser(userPin, serial)
res["set userpin"] = ret
count = count + 1
c.audit['action_detail'] += "userpin, "
if param.has_key("sopin"):
msg = "setting soPin failed"
soPin = getParam(param, "sopin", required)
serial = getParam(param, "serial", required)
# check admin authorization
checkPolicyPre('admin', 'setPin', param)
log.info("[setPin] setting soPin for token with serial %s" % serial)
ret = setPinSo(soPin, serial)
res["set sopin"] = ret
count = count + 1
c.audit['action_detail'] += "sopin, "
if count == 0 :
Session.rollback()
return sendError(response, ParameterError("Usage: %s" % description, id=77))
c.audit['success'] = count
Session.commit()
return sendResult(response, res, 1)
except PolicyException as pe:
log.error('[setPin] policy failed %r, %r' % (msg, pe))
log.error("[setPin] %s" % traceback.format_exc())
Session.rollback()
return sendError(response, unicode(pe), 1)
except Exception as e :
log.error('[setPin] %s :%r' % (msg, e))
log.error("[setPin] %s" % traceback.format_exc())
Session.rollback()
return sendError(response, unicode(e), 0)
finally:
Session.close()
log.debug('[setPin] done')
########################################################
[docs] def set(self):
"""
method:
admin/set
description:
this function is used to set many different values of a token.
arguments:
* serial - optional
* user - optional
* pin - optional - set the OTP PIN
* MaxFailCount - optional - set the maximum fail counter of a token
* SyncWindow - optional - set the synchronization window of the token
* OtpLen - optional - set the OTP Lenght of the token
* CounterWindow - optional - set the counter window (blank presses)
* hashlib - optioanl - set the hashing algo for HMAC tokens. This can be sha1, sha256, sha512
* timeWindow - optional - set the synchronize window for timebased tokens (in seconds)
* timeStep - optional - set the timestep for timebased tokens (usually 30 or 60 seconds)
* timeShift - optional - set the shift or timedrift of this token
* countAuthSuccessMax - optional - set the maximum allowed successful authentications
* countAuthSuccess\ - optional - set the counter of the successful authentications
* countAuth - optional - set the counter of authentications
* countAuthMax - optional - set the maximum allowed authentication tries
* validityPeriodStart - optional - set the start date of the validity period. The token can not be used before this date
* validityPeriodEnd - optional - set the end date of the validaity period. The token can not be used after this date
* phone - set the phone number for an SMS token
returns:
a json result with a boolean
"result": true
exception:
if an error occurs an exception is serialized and returned
"""
res = {}
count = 0
log.debug("[set]")
description = "set: parameters are\
pin\
MaxFailCount\
SyncWindow\
OtpLen\
CounterWindow\
hashlib\
timeWindow\
timeStep\
timeShift\
countAuthSuccessMax\
countAuthSuccess\
countAuth\
countAuthMax\
validityPeriodStart\
validityPeriodEnd\
description\
phone\
"
log.debug('[set]')
msg = ""
try:
param = getLowerParams(request.params)
serial = getParam(param, "serial", optional)
user = getUserFromParam(param, optional)
# check admin authorization
checkPolicyPre('admin', 'set', param, user=user)
## if there is a pin
if param.has_key("pin"):
msg = "[set] setting pin failed"
upin = getParam(param, "pin", required)
log.info("[set] setting pin for token with serial %r" % serial)
if 1 == getOTPPINEncrypt(serial=serial, user=user):
param['encryptpin'] = "True"
ret = setPin(upin, user, serial, param)
res["set pin"] = ret
count = count + 1
c.audit['action_detail'] += "pin, "
if param.has_key("MaxFailCount".lower()):
msg = "[set] setting MaxFailCount failed"
maxFail = int(getParam(param, "MaxFailCount".lower(), required))
log.info("[set] setting maxFailCount (%r) for token with serial %r" % (maxFail, serial))
ret = setMaxFailCount(maxFail, user, serial)
res["set MaxFailCount"] = ret
count = count + 1
c.audit['action_detail'] += "maxFailCount=%d, " % maxFail
if param.has_key("SyncWindow".lower()):
msg = "[set] setting SyncWindow failed"
syncWindow = int(getParam(param, "SyncWindow".lower(), required))
log.info("[set] setting syncWindow (%r) for token with serial %r" % (syncWindow, serial))
ret = setSyncWindow(syncWindow, user, serial)
res["set SyncWindow"] = ret
count = count + 1
c.audit['action_detail'] += "syncWindow=%d, " % syncWindow
if param.has_key("description".lower()):
msg = "[set] setting description failed"
description = getParam(param, "description".lower(), required)
log.info("[set] setting description (%r) for token with serial %r" % (description, serial))
ret = setDescription(description, user, serial)
res["set description"] = ret
count = count + 1
c.audit['action_detail'] += "description=%r, " % description
if param.has_key("CounterWindow".lower()):
msg = "[set] setting CounterWindow failed"
counterWindow = int(getParam(param, "CounterWindow".lower(), required))
log.info("[set] setting counterWindow (%r) for token with serial %r" % (counterWindow, serial))
ret = setCounterWindow(counterWindow, user, serial)
res["set CounterWindow"] = ret
count = count + 1
c.audit['action_detail'] += "counterWindow=%d, " % counterWindow
if param.has_key("OtpLen".lower()):
msg = "[set] setting OtpLen failed"
otpLen = int(getParam(param, "OtpLen".lower(), required))
log.info("[set] setting OtpLen (%r) for token with serial %r" % (otpLen, serial))
ret = setOtpLen(otpLen, user, serial)
res["set OtpLen"] = ret
count = count + 1
c.audit['action_detail'] += "otpLen=%d, " % otpLen
if param.has_key("hashlib".lower()):
msg = "[set] setting hashlib failed"
hashlib = getParam(param, "hashlib".lower(), required)
log.info("[set] setting hashlib (%r) for token with serial %r" % (hashlib, serial))
ret = setHashLib(hashlib, user, serial)
res["set hashlib"] = ret
count = count + 1
c.audit['action_detail'] += "hashlib=%s, " % unicode(hashlib)
if param.has_key("timeWindow".lower()):
msg = "[set] setting timeWindow failed"
timeWindow = int(getParam(param, "timeWindow".lower(), required))
log.info("[set] setting timeWindow (%r) for token with serial %r" % (timeWindow, serial))
ret = addTokenInfo("timeWindow", timeWindow , user, serial)
res["set timeWindow"] = ret
count = count + 1
c.audit['action_detail'] += "timeWindow=%d, " % timeWindow
if param.has_key("timeStep".lower()):
msg = "[set] setting timeStep failed"
timeStep = int(getParam(param, "timeStep".lower(), required))
log.info("[set] setting timeStep (%r) for token with serial %r" % (timeStep, serial))
ret = addTokenInfo("timeStep", timeStep , user, serial)
res["set timeStep"] = ret
count = count + 1
c.audit['action_detail'] += "timeStep=%d, " % timeStep
if param.has_key("timeShift".lower()):
msg = "[set] setting timeShift failed"
timeShift = int(getParam(param, "timeShift".lower(), required))
log.info("[set] setting timeShift (%r) for token with serial %r" % (timeShift, serial))
ret = addTokenInfo("timeShift", timeShift , user, serial)
res["set timeShift"] = ret
count = count + 1
c.audit['action_detail'] += "timeShift=%d, " % timeShift
if param.has_key("countAuth".lower()):
msg = "[set] setting countAuth failed"
ca = int(getParam(param, "countAuth".lower(), required))
log.info("[set] setting count_auth (%r) for token with serial %r" % (ca, serial))
tokens = getTokens4UserOrSerial(user, serial)
ret = 0
for tok in tokens:
tok.set_count_auth(int(ca))
count = count + 1
ret += 1
res["set countAuth"] = ret
c.audit['action_detail'] += "countAuth=%d, " % ca
if param.has_key("countAuthMax".lower()):
msg = "[set] setting countAuthMax failed"
ca = int(getParam(param, "countAuthMax".lower(), required))
log.info("[set] setting count_auth_max (%r) for token with serial %r" % (ca, serial))
tokens = getTokens4UserOrSerial(user, serial)
ret = 0
for tok in tokens:
tok.set_count_auth_max(int(ca))
count = count + 1
ret += 1
res["set countAuthMax"] = ret
c.audit['action_detail'] += "countAuthMax=%d, " % ca
if param.has_key("countAuthSuccess".lower()):
msg = "[set] setting countAuthSuccess failed"
ca = int(getParam(param, "countAuthSuccess".lower(), required))
log.info("[set] setting count_auth_success (%r) for token with serial %r" % (ca, serial))
tokens = getTokens4UserOrSerial(user, serial)
ret = 0
for tok in tokens:
tok.set_count_auth_success(int(ca))
count = count + 1
ret += 1
res["set countAuthSuccess"] = ret
c.audit['action_detail'] += "countAuthSuccess=%d, " % ca
if param.has_key("countAuthSuccessMax".lower()):
msg = "[set] setting countAuthSuccessMax failed"
ca = int(getParam(param, "countAuthSuccessMax".lower(), required))
log.info("[set] setting count_auth_success_max (%r) for token with serial %r" % (ca, serial))
tokens = getTokens4UserOrSerial(user, serial)
ret = 0
for tok in tokens:
tok.set_count_auth_success_max(int(ca))
count = count + 1
ret += 1
res["set countAuthSuccessMax"] = ret
c.audit['action_detail'] += "countAuthSuccessMax=%d, " % ca
if param.has_key("validityPeriodStart".lower()):
msg = "[set] setting validityPeriodStart failed"
ca = getParam(param, "validityPeriodStart".lower(), required)
log.info("[set] setting validity_period_start (%r) for token with serial %r" % (ca, serial))
tokens = getTokens4UserOrSerial(user, serial)
ret = 0
for tok in tokens:
tok.set_validity_period_start(ca)
count = count + 1
ret += 1
res["set validityPeriodStart"] = ret
c.audit['action_detail'] += u"validityPeriodStart=%s, " % unicode(ca)
if param.has_key("validityPeriodEnd".lower()):
msg = "[set] setting validityPeriodEnd failed"
ca = getParam(param, "validityPeriodEnd".lower(), required)
log.info("[set] setting validity_period_end (%r) for token with serial %r" % (ca, serial))
tokens = getTokens4UserOrSerial(user, serial)
ret = 0
for tok in tokens:
tok.set_validity_period_end(ca)
count = count + 1
ret += 1
res["set validityPeriodEnd"] = ret
c.audit['action_detail'] += "validityPeriodEnd=%s, " % unicode(ca)
if "phone" in param:
msg = "[set] setting phone failed"
ca = getParam(param, "phone".lower(), required)
log.info("[set] setting phone (%r) for token with serial %r" % (ca, serial))
tokens = getTokens4UserOrSerial(user, serial)
ret = 0
for tok in tokens:
tok.addToTokenInfo("phone", ca)
count = count + 1
ret += 1
res["set phone"] = ret
c.audit['action_detail'] += "phone=%s, " % unicode(ca)
if count == 0 :
Session.rollback()
return sendError(response, ParameterError("Usage: %s" % description, id=77))
c.audit['success'] = count
c.audit['user'] = user.login
c.audit['realm'] = user.realm
# DeleteMe: This code will never run, since getUserFromParam
# always returns a realm!
#if "" == c.audit['realm'] and "" != c.audit['user']:
# c.audit['realm'] = getDefaultRealm()
Session.commit()
return sendResult(response, res, 1)
except PolicyException as pe:
log.error('[set] policy failed: %s, %r' % (msg, pe))
log.error("[set] %s" % traceback.format_exc())
Session.rollback()
return sendError(response, unicode(pe), 1)
except Exception as e :
log.error('%s :%r' % (msg, e))
log.error("[set] %s" % traceback.format_exc())
Session.rollback()
return sendError(response, e)
finally:
Session.close()
log.debug('[set] done')
########################################################
[docs] def resync(self):
"""
method:
admin/resync - resync a token to a new counter
description:
this function resync the token, if the counter on server side is out of sync
with the physica token.
arguments:
* serial - serial or user required
* user - s.o.
* otp1 - the next otp to be found
* otp2 - the next otp after the otp1
returns:
a json result with a boolean
"result": true
exception:
if an error occurs an exception is serialized and returned
"""
log.debug("[resync]")
param = request.params
try:
serial = getParam(param, "serial", optional)
user = getUserFromParam(param, optional)
otp1 = getParam(param, "otp1", required)
otp2 = getParam(param, "otp2", required)
''' to support the challenge based resync, we have to pass the challenges
down to the token implementation
'''
chall1 = getParam(param, "challenge1", optional)
chall2 = getParam(param, "challenge2", optional)
options = None
if chall1 is not None and chall2 is not None:
options = {'challenge1' : chall1, 'challenge2':chall2 }
# check admin authorization
checkPolicyPre('admin', 'resync', param)
log.info("[resync] resyncing token with serial %r, user %r@%r"
% (serial, user.login, user.realm))
res = resyncToken(otp1, otp2, user, serial, options)
c.audit['success'] = res
c.audit['user'] = user.login
c.audit['realm'] = user.realm
if "" == c.audit['realm'] and "" != c.audit['user']:
c.audit['realm'] = getDefaultRealm()
Session.commit()
return sendResult(response, res, 1)
except PolicyException as pe:
log.error('[resync] policy failed %r' % pe)
log.error("[resync] %s" % traceback.format_exc())
Session.rollback()
return sendError(response, unicode(pe), 1)
except Exception as e:
log.error('[resync] resyncing token failed %r' % e)
log.error("[resync] %s" % traceback.format_exc())
Session.rollback()
return sendError(response, e, 1)
finally:
Session.close()
log.debug('[resync] done')
########################################################
[docs] def userlist(self):
"""
method:
admin/userlist - list all users
description:
lists the user in a realm
arguments:
* <searchexpr> - will be retrieved from the UserIdResolverClass
* realm - a realm, which is a collection of resolver configurations
* resConf - a destinct resolver configuration
returns:
a json result with a boolean
"result": true
exception:
if an error occurs an exception is serialized and returned
"""
users = []
param = request.params
# check admin authorization
# check if we got a realm or resolver, that is ok!
try:
realm = getParam(param, "realm", optional)
#_resolver = getParam(param, "resConf", optional)
checkPolicyPre('admin', 'userlist',
{ 'user': "dummy", 'realm':realm})
up = 0
user = getUserFromParam(param, optional)
log.info("[userlist] displaying users with param: %s, ", param)
if (len(user.realm) > 0):
up = up + 1
if (len(user.conf) > 0):
up = up + 1
# Here we need to list the users, that are only visible in the realm!!
# we could also only list the users in the realm, if the admin got
# the right "userlist".
### list searchfields if no other param
if len(param) == up:
usage = {"usage":"list available users matching the given search patterns:"}
usage["searchfields"] = getSearchFields(user)
res = usage
else:
users = getUserList(remove_session_from_param(param), user)
res = users
c.audit['success'] = True
c.audit['info'] = "realm: %s" % realm
Session.commit()
return sendResult(response, res)
except PolicyException as pe:
log.error('[userlist] policy failed %r' % pe)
log.error("[userlist] %s" % traceback.format_exc())
Session.rollback()
return sendError(response, unicode(pe), 1)
except Exception as e:
log.error("[userlist] failed %r" % e)
log.error("[userlist] %s" % traceback.format_exc())
Session.rollback()
return sendError(response, e)
finally:
Session.close()
log.debug("[userlist] done")
########################################################
[docs] def tokenrealm(self):
'''
method:
admin/tokenrealm - set the realms a token belongs to
description:
sets the realms of a token
arguments:
* serial - required - serialnumber of the token
* realms - required - comma seperated list of realms
'''
log.debug("[tokenrealm] calling tokenrealm")
param = request.params
try:
serial = getParam(param, "serial", required)
realms = getParam(param, "realms", required)
# check admin authorization
checkPolicyPre('admin', 'tokenrealm', param)
log.info("[tokenrealm] setting realms for token %s to %s" % (serial, realms))
realmList = realms.split(',')
ret = setRealms(serial, realmList)
c.audit['success'] = ret
c.audit['info'] = realms
Session.commit()
return sendResult(response, ret, 1)
except PolicyException as pe:
log.error('[tokenrealm] policy failed %r' % pe)
log.error("[tokenrealm] %s" % traceback.format_exc())
Session.rollback()
return sendError(response, unicode(pe), 1)
except Exception as e:
log.error('[tokenrealm] error setting realms for token %r' % e)
log.error("[tokenrealm] %s" % traceback.format_exc())
Session.rollback()
return sendError(response, e, 1)
finally:
Session.close()
log.debug("[tokenrealm] done")
########################################################
[docs] def reset(self):
"""
method:
admin/reset
description:
reset the FailCounter of a Token
arguments:
user or serial - to identify the tokens
returns:
a json result with a boolean
"result": true
exception:
if an error occurs an exception is serialized and returned
"""
log.debug("[reset]")
param = request.params
serial = getParam(param, "serial", optional)
user = getUserFromParam(param, optional)
try:
# check admin authorization
checkPolicyPre('admin', 'reset', param , user=user)
log.info("[reset] resetting the FailCounter for token with serial %s" % serial)
ret = resetToken(user, serial)
c.audit['success'] = ret
c.audit['user'] = user.login
c.audit['realm'] = user.realm
# DeleteMe: This code will never run, since getUserFromParam
# always returns a realm!
#if "" == c.audit['realm'] and "" != c.audit['user']:
# c.audit['realm'] = getDefaultRealm()
Session.commit()
return sendResult(response, ret)
except PolicyException as pe:
log.error('[reset] policy failed %r' % pe)
log.error("[reset] %s" % traceback.format_exc())
Session.rollback()
return sendError(response, unicode(pe), 1)
except Exception as exx:
log.error("[reset] Error resetting failcounter %r" % exx)
log.error("[reset] %s" % traceback.format_exc())
Session.rollback()
return sendError(response, exx)
finally:
Session.close()
log.debug("[reset] done")
########################################################
[docs] def copyTokenPin(self):
"""
method:
admin/copyTokenPin
description:
copies the token pin from one token to another
arguments:
* from - required - serial of token from
* to - required - serial of token to
returns:
a json result with a boolean
"result": true
exception:
if an error occurs an exception is serialized and returned
"""
log.debug("[copyTokenPin]")
ret = 0
err_string = ""
param = request.params
try:
serial_from = getParam(param, "from", required)
serial_to = getParam(param, "to", required)
# check admin authorization
checkPolicyPre('admin', 'copytokenpin', param)
log.info("[copyTokenPin] copying Pin from token %s to token %s" % (serial_from, serial_to))
ret = copyTokenPin(serial_from, serial_to)
c.audit['success'] = ret
c.audit['serial'] = serial_to
c.audit['action_detail'] = "from %s" % serial_from
err_string = unicode(ret)
if -1 == ret:
err_string = "can not get PIN from source token"
if -2 == ret:
err_string = "can not set PIN to destination token"
if 1 != ret:
c.audit['action_detail'] += ", " + err_string
c.audit['success'] = 0
Session.commit()
# Success
if 1 == ret:
return sendResult(response, True)
else:
return sendError(response, "copying token pin failed: %s" % err_string)
except PolicyException as pe:
log.error("[losttoken] Error doing losttoken %r" % pe)
log.error("[losttoken] %s" % traceback.format_exc())
Session.rollback()
return sendError(response, unicode(pe), 1)
except Exception as e:
log.error("[copyTokenPin] Error copying token pin")
Session.rollback()
return sendError(response, e)
finally:
Session.close()
########################################################
[docs] def copyTokenUser(self):
"""
method:
admin/copyTokenUser
description:
copies the token user from one token to another
arguments:
* from - required - serial of token from
* to - required - serial of token to
returns:
a json result with a boolean
"result": true
exception:
if an error occurs an exception is serialized and returned
"""
log.debug("[copyTokenUser]")
ret = 0
err_string = ""
param = request.params
try:
serial_from = getParam(param, "from", required)
serial_to = getParam(param, "to", required)
# check admin authorization
checkPolicyPre('admin', 'copytokenuser', param)
log.info("[copyTokenUser] copying User from token %s to token %s" % (serial_from, serial_to))
ret = copyTokenUser(serial_from, serial_to)
c.audit['success'] = ret
c.audit['serial'] = serial_to
c.audit['action_detail'] = "from %s" % serial_from
err_string = unicode(ret)
if -1 == ret:
err_string = "can not get user from source token"
if -2 == ret:
err_string = "can not set user to destination token"
if 1 != ret:
c.audit['action_detail'] += ", " + err_string
c.audit['success'] = 0
Session.commit()
# Success
if 1 == ret:
return sendResult(response, True)
else:
return sendError(response, "copying token user failed: %s" % err_string)
except PolicyException as pe:
log.error("[losttoken] Error doing losttoken %r" % pe)
log.error("[losttoken] %s" % traceback.format_exc())
Session.rollback()
return sendError(response, unicode(pe), 1)
except Exception as e:
log.error("[copyTokenUser] Error copying token user")
Session.rollback()
return sendError(response, e)
finally:
Session.close()
log.debug('[copyTokenUser] done')
########################################################
[docs] def losttoken(self):
"""
method:
admin/losttoken
description:
creates a new password token and copies the PIN and the
user of the old token to the new token.
The old token is disabled.
arguments:
* serial - serial of the old token
returns:
a json result with the new serial an the password
exception:
if an error occurs an exception is serialized and returned
"""
log.debug("[losttoken]")
ret = 0
res = {}
param = request.params
try:
serial = getParam(param, "serial", required)
# check admin authorization
checkPolicyPre('admin', 'losttoken', param)
res = losttoken(serial)
c.audit['success'] = ret
c.audit['serial'] = res.get('serial')
c.audit['action_detail'] = "from %s" % serial
Session.commit()
return sendResult(response, res)
except PolicyException as pe:
log.error("[losttoken] Error doing losttoken %r" % pe)
log.error("[losttoken] %s" % traceback.format_exc())
Session.rollback()
return sendError(response, unicode(pe), 1)
except Exception as e:
log.error("[losttoken] Error doing losttoken %r" % e)
log.error("[losttoken] %s" % traceback.format_exc())
Session.rollback()
return sendError(response, unicode(e))
finally:
Session.close()
log.debug('[losttoken] done')
########################################################
[docs] def loadtokens(self):
"""
method:
admin/loadtokens
description:
loads a whole token file to the server
arguments:
* file - the file in a post request
* type - the file type.
returns:
a json result with a boolean
"result": true
exception:
if an error occurs an exception is serialized and returned
"""
log.debug("[loadtokens]")
res = "Loading token file failed!"
known_types = ['aladdin-xml', 'oathcsv', 'yubikeycsv']
TOKENS = {}
res = None
sendResultMethod = sendResult
sendErrorMethod = sendError
from linotp.lib.ImportOTP import getKnownTypes
known_types.extend(getKnownTypes())
log.info("[loadtokens] importing linotp.lib. Known import types: %s" % known_types)
from linotp.lib.ImportOTP.PSKC import parsePSKCdata
log.info("[loadtokens] loaded parsePSKCdata")
from linotp.lib.ImportOTP.DPWplain import parseDPWdata
log.info("[loadtokens] loaded parseDPWdata")
from linotp.lib.ImportOTP.eTokenDat import parse_dat_data
log.info("[loadtokens] loaded parseDATdata")
from linotp.lib.ImportOTP.vasco import parseVASCOdata
log.info("[loadtokens] loaded parseVASCOdata")
try:
log.debug("[loadtokens] getting POST request")
log.debug("[loadtokens] %r" % request.POST)
tokenFile = request.POST['file']
fileType = request.POST['type']
pskc_type = None
pskc_password = None
pskc_preshared = None
pskc_checkserial = False
hashlib = None
if "pskc" == fileType:
pskc_type = request.POST['pskc_type']
pskc_password = request.POST['pskc_password']
pskc_preshared = request.POST['pskc_preshared']
if 'pskc_checkserial' in request.POST:
pskc_checkserial = True
fileString = ""
typeString = ""
log.debug("[loadtokens] loading token file to server using POST request. Filetype: %s. File: %s"
% (fileType, tokenFile))
# In case of form post requests, it is a "instance" of FieldStorage
# i.e. the Filename is selected in the browser and the data is transferred
# in an iframe. see: http://jquery.malsup.com/form/#sample4
#
if type(tokenFile).__name__ == 'instance':
log.debug("[loadtokens] Field storage file: %s", tokenFile)
fileString = tokenFile.value
sendResultMethod = sendXMLResult
sendErrorMethod = sendXMLError
else:
fileString = tokenFile
log.debug("[loadtokens] fileString: %s", fileString)
if type(fileType).__name__ == 'instance':
log.debug("[loadtokens] Field storage type: %s", fileType)
typeString = fileType.value
else:
typeString = fileType
log.debug("[loadtokens] typeString: <<%s>>", typeString)
if "pskc" == typeString:
log.debug("[loadtokens] passing password: %s, key: %s, checkserial: %s" % (pskc_password, pskc_preshared, pskc_checkserial))
if fileString == "" or typeString == "":
log.error("[loadtokens] file: %s", fileString)
log.error("[loadtokens] type: %s", typeString)
log.error("[loadtokens] Error loading/importing token file. file or type empty!")
return sendErrorMethod(response, "Error loading tokens. File or Type empty!")
if typeString not in known_types:
log.error("[loadtokens] Unknown file type: >>%s<<. We only know the types: %s" % (typeString, ', '.join(known_types)))
return sendErrorMethod(response, "Unknown file type: >>%s<<. We only know the types: %s" % (typeString, ', '.join(known_types)))
# Parse the tokens from file and get dictionary
if typeString == "aladdin-xml":
TOKENS = parseSafeNetXML(fileString)
# we only do hashlib for aladdin at the moment.
if 'aladdin_hashlib' in request.POST:
hashlib = request.POST['aladdin_hashlib']
elif typeString == "oathcsv":
TOKENS = parseOATHcsv(fileString)
elif typeString == "yubikeycsv":
TOKENS = parseYubicoCSV(fileString)
elif typeString == "dpw":
TOKENS = parseDPWdata(fileString)
elif typeString == "dat":
startdate = request.POST.get('startdate', None)
TOKENS = parse_dat_data(fileString, startdate)
elif typeString == "feitian":
TOKENS = parsePSKCdata(fileString, do_feitian=True)
elif typeString == "pskc":
if "key" == pskc_type:
TOKENS = parsePSKCdata(fileString, preshared_key_hex=pskc_preshared, do_checkserial=pskc_checkserial)
elif "password" == pskc_type:
TOKENS = parsePSKCdata(fileString, password=pskc_password, do_checkserial=pskc_checkserial)
#log.debug(TOKENS)
elif "plain" == pskc_type:
TOKENS = parsePSKCdata(fileString, do_checkserial=pskc_checkserial)
elif typeString == "vasco":
vasco_otplen = request.POST['vasco_otplen']
(fh, filename) = mkstemp()
f = open(filename, "w")
f.write(fileString)
f.close()
TOKENS = parseVASCOdata(filename, int(vasco_otplen))
os.remove(filename)
if TOKENS is None:
raise ImportException("Vasco DLL was not properly loaded. Importing of VASCO token not possible. Please check the log file for more details.")
log.debug("[loadtokens] read %i tokens. starting import now" % len(TOKENS))
# Now import the Tokens from the dictionary
ret = ""
for serial in TOKENS:
log.debug("[loadtokens] importing token %s" % TOKENS[serial])
# this needs to return the valid realms of the admin.
# it also checks the token number
res = checkPolicyPre('admin', 'import', {})
# we put the token in the FIRST realm of the admin.
# so tokenrealm will either be ONE realm or NONE
log.info("[loadtokens] setting tokenrealm %s" % res['realms'])
tokenrealm = None
if res['realms']:
tokenrealm = res.get('realms')[0]
log.info("[loadtokens] initialize token. serial: %s, realm: %s" % (serial, tokenrealm))
## for the eToken dat we assume, that it brings all its
## init parameters in correct format
if typeString == "dat":
init_param = TOKENS[serial]
else:
init_param = {'serial':serial,
'type':TOKENS[serial]['type'],
'description': TOKENS[serial].get("description", "imported"),
'otpkey' : TOKENS[serial]['hmac_key'],
'otplen' : TOKENS[serial].get('otplen'),
'timeStep' : TOKENS[serial].get('timeStep'),
'hashlib' : TOKENS[serial].get('hashlib')}
# add additional parameter for vasco tokens
if TOKENS[serial]['type'] == "vasco":
init_param['vasco_appl'] = TOKENS[serial]['tokeninfo'].get('application')
init_param['vasco_type'] = TOKENS[serial]['tokeninfo'].get('type')
init_param['vasco_auth'] = TOKENS[serial]['tokeninfo'].get('auth')
# add ocrasuite for ocra tokens, only if ocrasuite is not empty
if TOKENS[serial]['type'] == 'ocra':
if TOKENS[serial].get('ocrasuite', "") != "":
init_param['ocrasuite'] = TOKENS[serial].get('ocrasuite')
if hashlib and hashlib != "auto":
init_param['hashlib'] = hashlib
if tokenrealm:
checkPolicyPre('admin', 'loadtokens',
{'tokenrealm': tokenrealm })
(ret, tokenObj) = initToken(init_param, User('', '', ''),
tokenrealm=tokenrealm)
log.info ("[loadtokens] %i tokens imported." % len(TOKENS))
res = { 'value' : True, 'imported' : len(TOKENS) }
c.audit['info'] = "%s, %s (imported: %i)" % (fileType, tokenFile, len(TOKENS))
c.audit['serial'] = ', '.join(TOKENS.keys())
logTokenNum()
c.audit['success'] = ret
Session.commit()
return sendResultMethod(response, res)
except PolicyException as pe:
log.error("[loadtokens] Failed checking policy: %r" % pe)
log.error("[loadtokens] %s" % traceback.format_exc())
Session.rollback()
return sendError(response, unicode(pe), 1)
except Exception as e:
log.error("[loadtokens] failed! %r" % e)
log.error("[loadtokens] %s" % traceback.format_exc())
Session.rollback()
return sendErrorMethod(response, unicode(e))
finally:
Session.close()
log.debug('[loadtokens] done')
[docs] def testresolver(self):
"""
method:
admin/testresolver
description:
This method tests a useridresolvers configuration
arguments:
* type - "LDAP": depending on the type there are other parameters:
- "SQL"
* LDAP:
* BINDDN
* BINDPW
* LDAPURI
* TIMEOUT
* LDAPBASE
* LOGINNAMEATTRIBUTE
* LDAPSEARCHFILTER
* LDAPFILTER
* USERINFO
* LDAPSEARCHFILTER
* SIZELIMIT
* NOREFERRALS
* CACERTIFICATE
* SQL:
* Driver
* Server
* Port
* Database
* User
* Password
* Table
returns:
a json result with a boolean
"result": true
exception:
if an error occurs an exception is serialized and returned
"""
res = {}
try:
param = getLowerParams(request.params)
type = getParam(param, "type", required)
log.debug("[testresolver] testing resolver of type %s" % type)
if type == "ldap":
import useridresolver.LDAPIdResolver
param['BINDDN'] = getParam(param, "ldap_binddn", required)
param['BINDPW'] = getParam(param, "ldap_password", required)
param['LDAPURI'] = getParam(param, "ldap_uri", required)
param['TIMEOUT'] = getParam(param, "ldap_timeout", required)
param['LDAPBASE'] = getParam(param, "ldap_basedn", required)
param['LOGINNAMEATTRIBUTE'] = getParam(param, "ldap_loginattr", required)
param['LDAPSEARCHFILTER'] = getParam(param, "ldap_searchfilter", required)
param['LDAPFILTER'] = getParam(param, "ldap_userfilter", required)
param['USERINFO'] = getParam(param, "ldap_mapping", required)
param['SIZELIMIT'] = getParam(param, "ldap_sizelimit", required)
param['NOREFERRALS'] = getParam(param, "noreferrals", optional)
param['CACERTIFICATE'] = getParam(param, "ldap_certificate", optional)
(success, desc) = useridresolver.LDAPIdResolver.IdResolver.testconnection(param)
res['result'] = success
res['desc'] = desc
elif type == "sql":
import useridresolver.SQLIdResolver
param["Driver"] = getParam(param, "sql_driver", required)
param["Server"] = getParam(param, "sql_server", required)
param["Port"] = getParam(param, "sql_port", required)
param["Database"] = getParam(param, "sql_database", required)
param["User"] = getParam(param, "sql_user", required)
param["Password"] = getParam(param, "sql_password", required)
param["Table"] = getParam(param, "sql_table", required)
param["Where"] = getParam(param, "sql_where", optional)
(num, err_str) = useridresolver.SQLIdResolver.testconnection(param)
res['result'] = True
res['rows'] = num
res['err_string'] = err_str
Session.commit()
return sendResult(response, res)
except Exception as e:
log.error("[testresolver] failed: %r" % e)
log.error("[testresolver] %s" % traceback.format_exc())
Session.rollback()
return sendError(response, unicode(e), 1)
finally:
Session.close()
log.debug('[testresolver] done')
[docs] def checkstatus(self):
"""
show the status either
* of one dedicated challenge
* of all challenges of a token
* of all challenges belonging to all tokens of a user
:param transactionid/state: the transaction id of the challenge
:param serial: serial number of the token - will show all challenges
:param user:
:return: json result of token and challenges
"""
res = {}
param = {}
description = """
admin/checkstatus: check the token status -
for assynchronous verification. Missing parameter:
You need to provide one of the parameters "transactionid", "user" or "serial"'
"""
try:
param.update(request.params)
log.debug("[checkstatus] check challenge token status: %r" % param)
checkPolicyPre('admin', "checkstatus")
transid = param.get('transactionid', None) or param.get('state', None)
user = getUserFromParam(param, optional)
serial = getParam(param, 'serial' , optional)
if transid is None and user.isEmpty() and serial is None:
## raise exception
log.error("[admin/checkstatus] : missing parameter: "
"transactionid, user or serial number for token")
raise ParameterError("Usage: %s" % description, id=77)
## gather all challenges from serial, transactionid and user
challenges = set()
if serial is not None:
challenges.update(get_challenges(serial=serial))
if transid is not None :
challenges.update(get_challenges(transid=transid))
## if we have a user
if user.isEmpty() == False:
tokens = getTokens4UserOrSerial(user=user)
for token in tokens:
serial = token.getSerial()
challenges.update(get_challenges(serial=serial))
serials = set()
for challenge in challenges:
serials.add(challenge.getTokenSerial())
status = {}
## sort all information by token serial number
for serial in serials:
stat = {}
chall_dict = {}
## add the challenges info to the challenge dict
for challenge in challenges:
if challenge.getTokenSerial() == serial:
chall_dict[challenge.getTransactionId()] = challenge.get_vars(save=True)
stat['challenges'] = chall_dict
## add the token info to the stat dict
tokens = getTokens4UserOrSerial(serial=serial)
token = tokens[0]
stat['tokeninfo'] = token.get_vars(save=True)
## add the local stat to the summary status dict
status[serial] = stat
res['values'] = status
c.audit['success'] = res
Session.commit()
return sendResult(response, res, 1)
except PolicyException as pe:
log.error("[checkstatus] policy failed: %r" % pe)
log.error("[checkstatus] %s" % traceback.format_exc())
Session.rollback()
return sendError(response, unicode(pe))
except Exception as exx:
log.error("[checkstatus] failed: %r" % exx)
log.error("[checkstatus] %s" % traceback.format_exc())
Session.rollback()
return sendResult(response, unicode(exx), 0)
finally:
Session.close()
log.debug('[ocra/checkstatus] done')
#eof###########################################################################