def get(self): privkey = ds_settings.getSetting('privkey') privkey_ver = ds_settings.getSetting('privkey_ver') pubkey = utils.getPubkey(self, privkey) self.response.headers['Content-Type'] = 'application/x-x509-user-cert' self.response.headers['Content-Disposition'] = 'attachment; filename="'+privkey_ver+'.der"' self.response.out.write(pubkey)
def putGoogleSSO(gailUrl, pubkey): domain = os.environ['AUTH_DOMAIN'] email = ds_settings.getSetting('adminuser')+'@'+domain password = ds_settings.getSetting('adminpass') admin = gdata.apps.adminsettings.service.AdminSettingsService(email=email, domain=domain, password=password) try: admin.ProgrammaticLogin() except gdata.service.BadAuthentication: return(2) pubkey = b64encode(pubkey) admin.UpdateSSOSettings(enableSSO=True, samlSignonUri=gailUrl, samlLogoutUri=gailUrl, changePasswordUri=gailUrl+'password') admin.UpdateSSOKey(pubkey)
def putGoogleSSO(gailUrl, pubkey): domain = os.environ['AUTH_DOMAIN'] email = ds_settings.getSetting('adminuser') + '@' + domain password = ds_settings.getSetting('adminpass') admin = gdata.apps.adminsettings.service.AdminSettingsService( email=email, domain=domain, password=password) try: admin.ProgrammaticLogin() except gdata.service.BadAuthentication: return (2) pubkey = b64encode(pubkey) admin.UpdateSSOSettings(enableSSO=True, samlSignonUri=gailUrl, samlLogoutUri=gailUrl, changePasswordUri=gailUrl + 'password') admin.UpdateSSOKey(pubkey)
def GetGooglePubKey(self): domain = os.environ['AUTH_DOMAIN'] email = ds_settings.getSetting('adminuser')+'@'+domain password = ds_settings.getSetting('adminpass') admin = gdata.apps.adminsettings.service.AdminSettingsService(email=email, domain=domain, password=password) try: admin.ProgrammaticLogin() googlekey = admin.GetSSOKey() oid = ASN1Sequence(univ.ObjectIdentifier('1.2.840.113549.1.1.1'), univ.Null()) key = ASN1Sequence(univ.Integer(googlekey['modulus']), univ.Integer(googlekey['exponent'])) binkey = BytesToBin(encoder.encode(key)) pubkey = univ.BitString("'%s'B" % binkey) seq = ASN1Sequence(oid, pubkey) pubkeydata = encoder.encode(seq) except gdata.service.BadAuthentication: pubkeydata = 'failed' except gdata.apps.service.AppsForYourDomainException: pubkeydata = 'failed' return pubkeydata
def createAutoPostResponse (self, request, username): # takes a SAMLRequest and the username to sign in. Returns # signed XML SAMLResponse. Will redirect user to login page # if SAMLRequest has expired. domain = os.environ['AUTH_DOMAIN'] templatepath = os.path.join(os.path.dirname(__file__), 'templates') requestdata = unpackSAMLRequest(self, request) age = requestdata['requestage'] if (age < 0) or (age > 590): # is our SAMLRequest old or invalid? gailRedirect(self, 'https://mail.google.com/a/' + domain) ranchars = 'abcdefghijklmnop' responseid = '' assertid = '' for i in range(1, 40): responseid += ranchars[random.randint(0,15)] assertid += ranchars[random.randint(0,15)] template_values = { 'assertid': assertid, 'responseid': responseid, 'username': username, 'domain': domain, 'issueinstant': time.strftime('%Y-%m-%dT%H:%M:%SZ', time.gmtime()), 'authninstant': time.strftime('%Y-%m-%dT%H:%M:%SZ', time.gmtime()), 'acsurl': requestdata['acsurl'], 'providername': requestdata['providername'], 'requestid': requestdata['requestid'], 'notbefore': time.strftime('%Y-%m-%dT%H:%M:%SZ', time.gmtime(int(time.time()) - (5 * 60))), # 5 minutes ago 'notafter': time.strftime('%Y-%m-%dT%H:%M:%SZ', time.gmtime(int(time.time()) + (10 * 60))) # 10 minutes from now } responsepath = os.path.join(templatepath, 'response.xml') digestpath = os.path.join(templatepath, 'digest.xml') digestPart = template.render(digestpath, template_values) digestPart = digestPart[0:(len(digestPart) - 2)] # template adds \n\n at end of string, remove it digestSha1 = hashlib.sha1(digestPart) digest = b64encode(digestSha1.digest()) template_values.update({'digest': digest}) sipath = os.path.join(templatepath, 'response-signature-signedinfo.xml') signedInfo = template.render(sipath, template_values) signedInfo = signedInfo[0:(len(signedInfo) - 1)] # get rid of last newline key = gdata.tlslite.utils.keyfactory.parsePEMKey(ds_settings.getSetting('privkey'), private=True) signvalue = b64encode(key.hashAndSign(gdata.tlslite.utils.compat.stringToBytes(signedInfo))) modulus = numberToBase64(key.n) exponent = numberToBase64(key.e) template_values.update({'signvalue': signvalue, 'modulus': modulus, 'exponent': exponent}) responsepath = os.path.join(templatepath, 'response.xml') signedresponse = b64encode(template.render(responsepath, template_values)) autopostpath = os.path.join(templatepath, 'autopost.html') autopost_values = { 'acsurl': requestdata['acsurl'], 'signedresponse': signedresponse, 'relaystate': self.request.get('RelayState') # template takes care of escaping for IE } return template.render(autopostpath, autopost_values)
def userCanBecomeUser (apps, username, loginname): # Takes a apps resource, username and loginname. Checks to see if username has rights # to login as loginname using ADMINS_BECOME_USER or USERS_BECOME_USERS. Returns True/False. if ds_settings.getSetting('adminsbecomeusers').lower() == 'true': try: LookupUser = apps.RetrieveUser(username) if LookupUser.login.admin == 'true': return True except gdata.apps.service.AppsForYourDomainException , e: pass
def userCanBecomeUser(apps, username, loginname): # Takes a apps resource, username and loginname. Checks to see if username has rights # to login as loginname using ADMINS_BECOME_USER or USERS_BECOME_USERS. Returns True/False. if ds_settings.getSetting('adminsbecomeusers').lower() == 'true': try: LookupUser = apps.RetrieveUser(username) if LookupUser.login.admin == 'true': return True except gdata.apps.service.AppsForYourDomainException, e: pass
def post(self): domain = ds_settings.getSetting('domain') if os.environ['HTTP_REFERER']: orig_url = os.environ['HTTP_REFERER'] if orig_url.find('?') != -1: orig_url = orig_url[0:orig_url.find('?')] else: orig_url = '/password' username = str(self.request.get('username')) cpassword = str(self.request.get('cpassword')) npassword1 = str(self.request.get('npassword1')) npassword2 = str(self.request.get('npassword2')) if npassword1 != npassword2: utils.gailRedirect(self, orig_url + '?message_color=red&Message=Your%20Passwords%20Do%20Not%20Match') if len(npassword1) < 6: utils.gailRedirect(self, orig_url + '?message_color=red&Message=Your%20New%20Password%20Is%20To%20Short') apps = gdata.apps.service.AppsService(email=username+'@'+domain, domain=domain, password=cpassword) gdata.alt.appengine.run_on_appengine(apps, store_tokens=True, single_user_mode=True) try: apps.ProgrammaticLogin() except gdata.service.BadAuthentication: utils.gailRedirect(self, orig_url + '?message_color=red&Message=Unknown%20Username%20or%20Password') except gdata.service.CaptchaRequired: utils.gailRedirect(self, orig_url + '?message_color=red&Message=Your%20account%20is%20locked.%20%3Ca%20href%3D%22https%3A//www.google.com/a/'+domain+'/UnlockCaptcha%22%3EClick%20here%20to%20unlock%20it.%3C/a%3E') except: utils.gailRedirect(self, orig_url + '?message_color=red&Message=Unknown%20Error%20Confirming%20Password') apps2 = gdata.apps.service.AppsService(email=ds_settings.getSetting('adminuser')+'@'+domain, domain=domain, password=ds_settings.getSetting('adminpass')) gdata.alt.appengine.run_on_appengine(apps2, store_tokens=True, single_user_mode=True) try: apps2.ProgrammaticLogin() except: utils.gailRedirect(self, orig_url + '?message_color=red&Message=Unknown%20Error%20Changing%20Password.%20Please%20Report%This%To%Your%Administrator') user = apps2.RetrieveUser(username) user.login.password = npassword1 try: apps2.UpdateUser(username, user) except gdata.apps.service.AppsForYourDomainException , e: if e[0]['body'].find('InvalidPassword'): utils.gailRedirect(self, orig_url + '?message_color=red&Message=Your%20New%20Password%20Is%20Invalid.%20Try%20A%20Longer%20Password.') else: utils.gailRedirect(self, orig_url + '?message_color=red&Message=Unknown%20Error%20Attempting%20To%20Change%20Password.%20Please%20Report%20This%20To%20Your%20Administrator')
def GetGooglePubKey(self): domain = os.environ['AUTH_DOMAIN'] email = ds_settings.getSetting('adminuser') + '@' + domain password = ds_settings.getSetting('adminpass') admin = gdata.apps.adminsettings.service.AdminSettingsService( email=email, domain=domain, password=password) try: admin.ProgrammaticLogin() googlekey = admin.GetSSOKey() oid = ASN1Sequence(univ.ObjectIdentifier('1.2.840.113549.1.1.1'), univ.Null()) key = ASN1Sequence(univ.Integer(googlekey['modulus']), univ.Integer(googlekey['exponent'])) binkey = BytesToBin(encoder.encode(key)) pubkey = univ.BitString("'%s'B" % binkey) seq = ASN1Sequence(oid, pubkey) pubkeydata = encoder.encode(seq) except gdata.service.BadAuthentication: pubkeydata = 'failed' except gdata.apps.service.AppsForYourDomainException: pubkeydata = 'failed' return pubkeydata
def get(self): template_values = {} template_values['appspot_domain'] = os.environ['APPLICATION_ID']+'.appspot.com' template_values['domain'] = os.environ['AUTH_DOMAIN'] template_values['adminuser'] = ds_settings.getSetting('adminuser') template_values['adminsbecomeusers'] = ds_settings.getSetting('adminsbecomeusers') template_values['usersbecomeusers'] = ds_settings.getSetting('usersbecomeusers') template_values['adminpass'] = '******' privkey = ds_settings.getSetting('privkey') if privkey != None: gailpubkey = utils.getPubkey(self, privkey) else: gailpubkey = 'failed' googlepubkey = utils.GetGooglePubKey(self) if gailpubkey == 'failed': template_values['keymatch'] = 'GAIL has no keys!' elif googlepubkey == 'failed': template_values['keymatch'] = 'Failed to get Google Public Key' elif gailpubkey == googlepubkey: template_values['keymatch'] = 'Yes' else: template_values['keymatch'] = 'No' self.response.out.write(ds_templates.templateRender('gailadmin.html', template_values))
def get(self): privkey = ds_settings.getSetting('privkey') pubkey = utils.getPubkey(self, privkey) gailUrl = 'https://'+os.environ['APPLICATION_ID']+'.appspot.com/' utils.putGoogleSSO(gailUrl, pubkey) utils.gailRedirect(self, '/gailadmin')
'providername': requestxml.firstChild.attributes['ProviderName'].value, 'requestid': requestxml.firstChild.attributes['ID'].value } def userCanBecomeUser (apps, username, loginname): # Takes a apps resource, username and loginname. Checks to see if username has rights # to login as loginname using ADMINS_BECOME_USER or USERS_BECOME_USERS. Returns True/False. if ds_settings.getSetting('adminsbecomeusers').lower() == 'true': try: LookupUser = apps.RetrieveUser(username) if LookupUser.login.admin == 'true': return True except gdata.apps.service.AppsForYourDomainException , e: pass if ds_settings.getSetting('usersbecomeusers').lower() == 'true': # Only admins can do group lookups via prov. API so we must login as one domain = os.environ['AUTH_DOMAIN'] adminuser = ds_settings.getSetting('adminuser') adminpass = ds_settings.getSetting('adminpass') groupsadmin = gdata.apps.groups.service.GroupsService(adminuser+'@'+domain, domain=domain, password=adminpass) gdata.alt.appengine.run_on_appengine(groupsadmin, store_tokens=True, single_user_mode=True) try: groupsadmin.ProgrammaticLogin() except gdata.service.BadAuthentication: gailRedirect(self, '/?SAMLRequest='+urllib.quote(self.request.get('SAMLRequest'))+'&RelayState='+urllib.quote(self.request.get('RelayState'))+'&Error=Invalid%20GAIL%20settings.%20Please%20talk%20to%20your%20network%20administrator.') lists = groupsadmin.RetrieveGroups(username) for group in lists: if re.match('.*-become@'+domain, group['groupId'].lower()): #see if loginname matches this group name (minus the -become) #or if loginname is a member of this group (minus the -become)
def createAutoPostResponse(self, request, username): # takes a SAMLRequest and the username to sign in. Returns # signed XML SAMLResponse. Will redirect user to login page # if SAMLRequest has expired. domain = os.environ['AUTH_DOMAIN'] templatepath = os.path.join(os.path.dirname(__file__), 'templates') requestdata = unpackSAMLRequest(self, request) age = requestdata['requestage'] if (age < 0) or (age > 590): # is our SAMLRequest old or invalid? gailRedirect(self, 'https://mail.google.com/a/' + domain) ranchars = 'abcdefghijklmnop' responseid = '' assertid = '' for i in range(1, 40): responseid += ranchars[random.randint(0, 15)] assertid += ranchars[random.randint(0, 15)] template_values = { 'assertid': assertid, 'responseid': responseid, 'username': username, 'domain': domain, 'issueinstant': time.strftime('%Y-%m-%dT%H:%M:%SZ', time.gmtime()), 'authninstant': time.strftime('%Y-%m-%dT%H:%M:%SZ', time.gmtime()), 'acsurl': requestdata['acsurl'], 'providername': requestdata['providername'], 'requestid': requestdata['requestid'], 'notbefore': time.strftime('%Y-%m-%dT%H:%M:%SZ', time.gmtime(int(time.time()) - (5 * 60))), # 5 minutes ago 'notafter': time.strftime('%Y-%m-%dT%H:%M:%SZ', time.gmtime(int(time.time()) + (10 * 60))) # 10 minutes from now } responsepath = os.path.join(templatepath, 'response.xml') digestpath = os.path.join(templatepath, 'digest.xml') digestPart = template.render(digestpath, template_values) digestPart = digestPart[0:( len(digestPart) - 2)] # template adds \n\n at end of string, remove it digestSha1 = hashlib.sha1(digestPart) digest = b64encode(digestSha1.digest()) template_values.update({'digest': digest}) sipath = os.path.join(templatepath, 'response-signature-signedinfo.xml') signedInfo = template.render(sipath, template_values) signedInfo = signedInfo[0:(len(signedInfo) - 1)] # get rid of last newline key = gdata.tlslite.utils.keyfactory.parsePEMKey( ds_settings.getSetting('privkey'), private=True) signvalue = b64encode( key.hashAndSign(gdata.tlslite.utils.compat.stringToBytes(signedInfo))) modulus = numberToBase64(key.n) exponent = numberToBase64(key.e) template_values.update({ 'signvalue': signvalue, 'modulus': modulus, 'exponent': exponent }) responsepath = os.path.join(templatepath, 'response.xml') signedresponse = b64encode(template.render(responsepath, template_values)) autopostpath = os.path.join(templatepath, 'autopost.html') autopost_values = { 'acsurl': requestdata['acsurl'], 'signedresponse': signedresponse, 'relaystate': self.request.get( 'RelayState') # template takes care of escaping for IE } return template.render(autopostpath, autopost_values)
'requestid': requestxml.firstChild.attributes['ID'].value } def userCanBecomeUser(apps, username, loginname): # Takes a apps resource, username and loginname. Checks to see if username has rights # to login as loginname using ADMINS_BECOME_USER or USERS_BECOME_USERS. Returns True/False. if ds_settings.getSetting('adminsbecomeusers').lower() == 'true': try: LookupUser = apps.RetrieveUser(username) if LookupUser.login.admin == 'true': return True except gdata.apps.service.AppsForYourDomainException, e: pass if ds_settings.getSetting('usersbecomeusers').lower() == 'true': # Only admins can do group lookups via prov. API so we must login as one domain = os.environ['AUTH_DOMAIN'] adminuser = ds_settings.getSetting('adminuser') adminpass = ds_settings.getSetting('adminpass') groupsadmin = gdata.apps.groups.service.GroupsService( adminuser + '@' + domain, domain=domain, password=adminpass) gdata.alt.appengine.run_on_appengine(groupsadmin, store_tokens=True, single_user_mode=True) try: groupsadmin.ProgrammaticLogin() except gdata.service.BadAuthentication: gailRedirect( self, '/?SAMLRequest=' + urllib.quote(self.request.get('SAMLRequest')) +