def _callback(res): t = res["licenseKey"] _log.info("received test license: %s" % t) # parse the test license: we don't want to "taint" rdf with an invalid license license_ok = False try: from codebay.common import licensekey val, broken = licensekey.decode_license(t) if val is None: raise Exception("license is broken, groups: %s" % broken) license_ok = True except: _log.exception("test license is broken, ignoring") # store test license & force reidentify if license_ok: _log.info("received test license passes sanity check, storing") ui_root = helpers.get_ui_config() ui_root.setS(ns_ui.testLicenseKey, rdf.String, t) ign = self.managementconnection.trigger_reidentify() # returns deferred # re-export database if license_ok: @db.untransact() def _export(): try: self._export_rdf_database() except: _log.exception("failed to export rdf database (test license assigned)") _export()
def submitted(self, ctx, form, data): fda = formalutils.FormDataAccessor(form, [], ctx) pd = uidatahelpers.CreateProtocolData() # Save collapsed states first, so they feed back to next round for [rdf_uri, key] in [[ns_ui.collapseLicense, 'license_group'], [ns_ui.collapseLocale, 'locale_group'], [ns_ui.collapseProductMaintenance, 'reboot_group'], [ns_ui.collapseSnmp, 'snmp_group'], [ns_ui.collapseRemoteManagement, 'remote_group'], [ns_ui.collapseSslCertificate, 'ssl_group']]: try: # XXX: passing of the hidden _collapsedstate_ parameter is not too clean uihelpers.update_collapse_setting( rdf_uri, fda['%s._collapsedstate_' % key]) except: _log.exception('error updating collapsed state for %s' % rdf_uri) try: # global canonicalization tmp = fda.descend('license_group') if tmp.has_key('license_key') and (tmp['license_key'] is not None): tmp['license_key'] = tmp['license_key'].upper().strip() # global validation tmp = fda.descend('license_group') if tmp.has_key('license_key') and (tmp['license_key'] is not None): val, grps = None, None try: val, grps = licensekey.decode_license(tmp['license_key']) except: _log.exception('license decoding failed') if val is None: tmp.add_error('license_key', 'Invalid license key') tmp = fda.descend('remote_group') if tmp.has_key('root_password1') and tmp.has_key('root_password2'): pw1, pw2 = tmp['root_password1'], tmp['root_password2'] if pw1 is None: pw1 = '' if pw2 is None: pw2 = '' if pw1 != pw2: tmp.add_error('root_password1', 'Passwords do not match') tmp.add_error('root_password2', 'Passwords do not match') else: if not helpers.check_unix_password_characters(pw1): tmp.add_error('root_password1', 'Invalid characters in password') tmp.add_error('root_password2', 'Invalid characters in password') tmp = fda.descend('snmp_group') if tmp.has_key( 'snmp_community') and tmp['snmp_community'] is not None: if not uihelpers.check_snmp_community_characters( tmp['snmp_community']): tmp.add_error('snmp_community', 'Invalid characters') # # XXX -- How to validate SSL certificates reliably? Currently invalid # certificate / key causes VPNease to use self-signed version so it's # relatively OK. # # # XXX -- admin smtp setting validation & normalization # # Intermediate early bail out to avoid saving if there are errors fda.finalize_validation() # Deep copy UI config to 'new' UI config pd.clone_ui_config() # save data self.save_ui_data(ctx, form, data) # re-create protocol data to see if new exceptions crop up pd.save_protocol_data() except: _log.exception( 'validation failed unexpectedly, adding global error') fda.add_global_error('Unknown validation error') # finalize; raises if something wrong fda.finalize_validation() # locale settings are handled directly cfg_ui = helpers.get_new_ui_config() try: cfg_ui.setS(ns_ui.timezone, rdf.String, fda['locale_group.timezone']) cfg_ui.setS(ns_ui.keymap, rdf.String, fda['locale_group.keymap']) gnomeconfig.set_keymap_settings( cfg_ui.getS(ns_ui.keymap, rdf.String)) except: _log.exception('activating timezone and keymap settings failed') # same with root password try: tmp = fda.descend('remote_group') if tmp.has_key('root_password1') and tmp.has_key('root_password2'): pw1, pw2 = tmp['root_password1'], tmp['root_password2'] if (pw1 == '') and (pw2 == ''): pass elif (pw1 == None) and (pw2 == None): pass elif pw1 == pw2: # change password; we assume it converts to ascii nicely helpers.change_unix_password('root', str(pw1)) else: # should not come here _log.error('passwords differ after validation, ignoring') except: _log.exception('changing root password failed') # activate new config pd.activate_protocol_data() # update initial config saved flag pd.update_initial_config_saved() # # XXX: It would be cleaner if we could first stop the runner, then change the # config, and then restart it. If we do that with a deferred, then it is possible # that the user changes the config again before we have time to activate it. # Putting the config into some sort of "staging area" might help. Currently we # simply assume that runner stop (and start) are robust enough. # # # XXX: If timezone has changed, we should re-render graphs immediately so they # will have the correct timezone when status pages are loaded. # # ssl certificate - always rewrite here try: uihelpers.update_ssl_certificate_files() # reread files; we don't regenerate because we never overwrite the self-signed # certificate here self.master.reread_ssl_files() except: _log.exception('ssl certificate check failed') # stop, configure, start followup = uihelpers.build_uri(ctx, 'status/main.html') return uihelpers.reconfigure_and_restart_page(self.master, ctx, followup_uri=followup)
def submitted(self, ctx, form, data): fda = formalutils.FormDataAccessor(form, [], ctx) pd = uidatahelpers.CreateProtocolData() # Save collapsed states first, so they feed back to next round for [rdf_uri, key] in [ [ ns_ui.collapseLicense, 'license_group' ], [ ns_ui.collapseLocale, 'locale_group' ], [ ns_ui.collapseProductMaintenance, 'reboot_group' ], [ ns_ui.collapseSnmp, 'snmp_group' ], [ ns_ui.collapseRemoteManagement, 'remote_group' ], [ ns_ui.collapseSslCertificate, 'ssl_group' ] ]: try: # XXX: passing of the hidden _collapsedstate_ parameter is not too clean uihelpers.update_collapse_setting(rdf_uri, fda['%s._collapsedstate_' % key]) except: _log.exception('error updating collapsed state for %s' % rdf_uri) try: # global canonicalization tmp = fda.descend('license_group') if tmp.has_key('license_key') and (tmp['license_key'] is not None): tmp['license_key'] = tmp['license_key'].upper().strip() # global validation tmp = fda.descend('license_group') if tmp.has_key('license_key') and (tmp['license_key'] is not None): val, grps = None, None try: val, grps = licensekey.decode_license(tmp['license_key']) except: _log.exception('license decoding failed') if val is None: tmp.add_error('license_key', 'Invalid license key') tmp = fda.descend('remote_group') if tmp.has_key('root_password1') and tmp.has_key('root_password2'): pw1, pw2 = tmp['root_password1'], tmp['root_password2'] if pw1 is None: pw1 = '' if pw2 is None: pw2 = '' if pw1 != pw2: tmp.add_error('root_password1', 'Passwords do not match') tmp.add_error('root_password2', 'Passwords do not match') else: if not helpers.check_unix_password_characters(pw1): tmp.add_error('root_password1', 'Invalid characters in password') tmp.add_error('root_password2', 'Invalid characters in password') tmp = fda.descend('snmp_group') if tmp.has_key('snmp_community') and tmp['snmp_community'] is not None: if not uihelpers.check_snmp_community_characters(tmp['snmp_community']): tmp.add_error('snmp_community', 'Invalid characters') # # XXX -- How to validate SSL certificates reliably? Currently invalid # certificate / key causes VPNease to use self-signed version so it's # relatively OK. # # # XXX -- admin smtp setting validation & normalization # # Intermediate early bail out to avoid saving if there are errors fda.finalize_validation() # Deep copy UI config to 'new' UI config pd.clone_ui_config() # save data self.save_ui_data(ctx, form, data) # re-create protocol data to see if new exceptions crop up pd.save_protocol_data() except: _log.exception('validation failed unexpectedly, adding global error') fda.add_global_error('Unknown validation error') # finalize; raises if something wrong fda.finalize_validation() # locale settings are handled directly cfg_ui = helpers.get_new_ui_config() try: cfg_ui.setS(ns_ui.timezone, rdf.String, fda['locale_group.timezone']) cfg_ui.setS(ns_ui.keymap, rdf.String, fda['locale_group.keymap']) gnomeconfig.set_keymap_settings(cfg_ui.getS(ns_ui.keymap, rdf.String)) except: _log.exception('activating timezone and keymap settings failed') # same with root password try: tmp = fda.descend('remote_group') if tmp.has_key('root_password1') and tmp.has_key('root_password2'): pw1, pw2 = tmp['root_password1'], tmp['root_password2'] if (pw1 == '') and (pw2 == ''): pass elif (pw1 == None) and (pw2 == None): pass elif pw1 == pw2: # change password; we assume it converts to ascii nicely helpers.change_unix_password('root', str(pw1)) else: # should not come here _log.error('passwords differ after validation, ignoring') except: _log.exception('changing root password failed') # activate new config pd.activate_protocol_data() # update initial config saved flag pd.update_initial_config_saved() # # XXX: It would be cleaner if we could first stop the runner, then change the # config, and then restart it. If we do that with a deferred, then it is possible # that the user changes the config again before we have time to activate it. # Putting the config into some sort of "staging area" might help. Currently we # simply assume that runner stop (and start) are robust enough. # # # XXX: If timezone has changed, we should re-render graphs immediately so they # will have the correct timezone when status pages are loaded. # # ssl certificate - always rewrite here try: uihelpers.update_ssl_certificate_files() # reread files; we don't regenerate because we never overwrite the self-signed # certificate here self.master.reread_ssl_files() except: _log.exception('ssl certificate check failed') # stop, configure, start followup = uihelpers.build_uri(ctx, 'status/main.html') return uihelpers.reconfigure_and_restart_page(self.master, ctx, followup_uri=followup)
def _parse_csv(f): import csv # XXX: UTC? def _parse_date(x): # 2008-05-01 if x in ['ANY', '']: return None grp = _re_date.match(x).groups() return datetime.datetime(int(grp[0]), int(grp[1]), int(grp[2])) # dummy date used for disabled licenses inv_date = datetime.datetime(1980, 1, 1) res = [] reader = csv.reader(f) for row in reader: try: if len(row) < 7: continue decrow = [] for i in xrange(len(row)): decrow.append(row[i].decode('utf-8').strip()) lkey = decrow[0] if len(lkey) != (5*5 + 4): continue try: (val, broken) = licensekey.decode_license(lkey) if val is None: raise Exception('invalid license key') except: _log.warning('skipping invalid license key: %s, row: %s' % (lkey, repr(decrow))) continue # process row lkey = decrow[0].upper() lstr = decrow[1] lstatus = decrow[2].upper() if lstr == '': pass if lstatus == '': raise Exception('invalid license status') if not (lstatus in ['FLOATING', 'ACTIVE', 'DISABLED']): raise Exception('invalid license status: %s' % lstatus) if lstatus == 'FLOATING': lvalidfrom = None lvalidto = None lusers = 100 ls2s = 100 lstr = 'Floating license' elif lstatus == 'DISABLED': lvalidfrom = inv_date lvalidto = inv_date lusers = 0 ls2s = 0 lstr = 'Disabled' elif lstatus == 'ACTIVE': lvalidfrom = _parse_date(decrow[3]) lvalidto = _parse_date(decrow[4]) lusers = int(decrow[5]) ls2s = int(decrow[6]) else: raise Exception('invalid status for license, did not expect to get here') res.append(CustomerLicense(lkey, lvalidfrom, lvalidto, lstr, lusers, ls2s)) except: _log.exception('failed to process license csv row: %s' % repr(row)) return res
def license_lookup(self, res, arg_licenseKey): now = datetime.datetime.utcnow() # anonymous license? if arg_licenseKey == '': # empty license key is anonymous self._fill_in_unknown_license(res, now) return # non-anonymous; check syntax first try: _log.debug('checking license syntax for: %s' % arg_licenseKey) ign = str(arg_licenseKey) # check that no Unicode chars (val, broken) = licensekey.decode_license(arg_licenseKey) _log.debug('=> result %s, %s' % (val, broken)) if val is None: raise Exception('one or more groups broken') except: # FIXME: wide... _log.error('invalid license key: %s' % arg_licenseKey) raise managementprotocol.InvalidLicenseError('Invalid license key: %s' % str(arg_licenseKey)) # check for a demo license dlic = None try: dlic = self.get_demo_license(arg_licenseKey) except: _log.exception('failed to get demo license info') # check for a customer license? clic = None try: clic = self.get_customer_license_information(arg_licenseKey) except: _log.exception('failed to get customer license info') # get basic license parameters before validity time computation _log.debug('clic=%s, dlic=%s' % (clic, dlic)) if clic is not None: _log.info('found a full customer license for %s' % arg_licenseKey) is_demo = False customer_validity_start = clic.validity_start customer_validity_end = clic.validity_end demo_validity_start = now demo_validity_end = now user_count = clic.user_count s2s_count = clic.site_to_site_count license_string = clic.license_string elif dlic is not None: _log.info('found a demo license') is_demo = True customer_validity_start = dlic.grant_time customer_validity_end = customer_validity_start + msconstants.DEMO_LICENSE_TIME demo_validity_start = customer_validity_start demo_validity_end = customer_validity_end user_count = msconstants.DEMO_LICENSE_USER_COUNT s2s_count = msconstants.DEMO_LICENSE_SITE_TO_SITE_COUNT license_string = 'Demo license' else: _log.warning('no license info found for license key %s, returning unknown' % arg_licenseKey) self._fill_in_unknown_license(res, now) return # compute temporary validity and recheck time, i.e. time that server # can operate withouch rechecking license_in_validity_period, validity_start, validity_end, recheck_time = self._compute_temporary_validity_period(customer_validity_start, customer_validity_end) # license status if license_in_validity_period: license_status = u'VALID' else: # FIXME: license is valid even if it has been expired... ??? license_status = u'DISABLED' # license parameters are now ready res['licenseMaxRemoteAccessConnections'] = user_count res['licenseMaxSiteToSiteConnections'] = s2s_count res['licenseValidityStart'] = validity_start res['licenseValidityEnd'] = validity_end res['licenseRecheckLatestAt'] = recheck_time res['licenseString'] = license_string res['licenseStatus'] = license_status res['isDemoLicense'] = is_demo res['demoValidityStart'] = demo_validity_start res['demoValidityEnd'] = demo_validity_end