def generateDN(self, **kwargs): """Get DN of the user certificate that will be created :param dict kwargs: user description dictionary with possible fields: - FullName or CN - Email or emailAddress :return: S_OK(str)/S_ERROR() -- contain DN """ if kwargs.get("FullName"): kwargs["CN"] = [kwargs["FullName"]] if kwargs.get("Email"): kwargs["emailAddress"] = [kwargs["Email"]] self.__X509Name = X509.X509_Name() self.log.info("Creating distinguished names chain") for nid in self.supplied: if nid not in [self.fields2nid[f] for f in self.dnList]: return S_ERROR( 'DNs order list does not contain supplied DN "%s"' % self.nid2defField.get(nid, min(self.nid2fields[nid], key=len))) for field in self.dnList: values = [] nid = self.fields2nid[field] if nid in self.match: for field in self.nid2fields[nid]: if field in self.dnInfoDictCA: values = self.dnInfoDictCA[field] if not values: return S_ERROR('Not found "%s" match DN in CA' % field) for field in self.nid2fields[nid]: if kwargs.get(field): values = kwargs[field] if isinstance( kwargs[field], list) else [kwargs[field]] if not values and nid in self.supplied: # Search default value if nid not in self.nid2defField: return S_ERROR('No values set for "%s" DN' % min(self.nid2fields[nid], key=len)) values = self.parameters[nid] result = self.__fillX509Name(field, values) if not result["OK"]: return result # WARN: This logic not support list of distribtes name elements resDN = m2.x509_name_oneline(self.__X509Name.x509_name) # pylint: disable=no-member result = self.checkStatus(resDN) if not result["OK"]: return result return S_OK(resDN)
def __str__(self): # type: () -> bytes assert m2.x509_name_type_check(self.x509_name), \ "'x509_name' type error" return m2.x509_name_oneline(self.x509_name)
def getUserDN(self, userDict=None, sessionDict=None, userDN=None): """ Get DN of the user certificate that will be created :param dict userDict: user description dictionary with possible fields: FullName, UserName, DN, EMail, DiracGroup :param dict sessionDict: session dictionary :param basestring userDN: user DN :return: S_OK()/S_ERROR(), Value is the DN string """ chain = X509Chain() result = chain.loadChainFromFile(self.parameters['CertFile']) if not result['OK']: return result result = chain.getCredentials() if not result['OK']: return result caDN = result['Value']['subject'] caDict = dict([field.split('=') for field in caDN.lstrip('/').split('/')]) caFieldByNid = dict([[self.fs2nid[field], field] for field in caDict]) dnDict = {} if userDN: self.log.info('Checking %s user DN' % userDN) dnDict = dict([field.split('=') for field in userDN.lstrip('/').split('/')]) dnFieldByNid = dict([[self.fs2nid[field], field] for field in dnDict]) for nid in self.supplied: if nid not in dnFieldByNid: return S_ERROR('Current DN is invalid, "%s" field must be set.' % dnFieldByNid[nid]) for nid in dnFieldByNid: if nid not in self.supplied + self.match + self.optional: return S_ERROR('Current DN is invalid, "%s" field is not found for current CA.' % dnFieldByNid[nid]) if nid in self.match and not caDict[caFieldByNid[nid]] == dnDict[dnFieldByNid[nid]]: return S_ERROR('Current DN is invalid, "%s" field must be %s.' % (dnFieldByNid[nid], caDict[caFieldByNid[nid]])) if nid in self.maxDict and len(dnDict[dnFieldByNid[nid]]) > self.maxDict[nid]: return S_ERROR('Current DN is invalid, "%s" field must be less then %s.' % (dnDict[dnFieldByNid[nid]], self.maxDict[nid])) if nid in self.minDict and len(dnDict[dnFieldByNid[nid]]) < self.minDict[nid]: return S_ERROR('Current DN is invalid, "%s" field must be more then %s.' % (dnDict[dnFieldByNid[nid]], self.minDict[nid])) for k, v in dnDict.items(): if self.defDict.get(k): self.defDict[k] = v if self.fs2nid[k] == self.fs2nid['CN']: userDict['FullName'] = v if self.fs2nid[k] == self.fs2nid['emailAddress']: userDict['EMail'] = v else: result = self.checkStatus(userDict) if not result['OK']: return result # Fill DN subject name self.log.info('Creating distributes names chain') for nid in self.match: if nid not in caFieldByNid: return S_ERROR('Distributes name(%s) must be present in CA certificate.' % ', '.join(self.n2fields[nid])) result = self.__fillX509Name(caFieldByNid[nid], caDict[caFieldByNid[nid]]) if not result['OK']: return result for nid in self.supplied: if self.defDict.get(self.n2field[nid]): result = self.__fillX509Name(self.n2field[nid], self.defDict[self.n2field[nid]]) if not result['OK']: return result for nid, value in [(self.fs2nid['CN'], userDict['FullName']), (self.fs2nid['emailAddress'], userDict['EMail'])]: if nid in self.supplied + self.optional: result = self.__fillX509Name(self.n2field[nid], value) if not result['OK']: return result # WARN: This logic not support list of distribtes name elements resDN = m2.x509_name_oneline(self.__X509Name.x509_name) # pylint: disable=no-member if userDN and not userDN == resDN: return S_ERROR('%s not match with generated DN: %s' % (userDN, resDN)) return S_OK(resDN)