def update_one_corp(corp): my_corp = Corporation.objects.mine() auth_url = urlparse.urljoin(corp.ecm_url, '/corp/auth/startsession/') client = HttpClient() LOG.debug('Establishing secure data exchange with %r...' % corp.ecm_url) response = client.get( auth_url, headers={'Authorization': 'RSA %s' % my_corp.key_fingerprint}) cipher_txt_in = response.read() # we decrypt the response with our private key session_secret = crypto.rsa_decrypt(my_corp.private_key, cipher_txt_in) # and encrypt it back with the corp's public key cipher_txt_out = crypto.rsa_encrypt(corp.public_key, session_secret) # then send it to the server client.post(auth_url, cipher_txt_out) LOG.debug('Fetching which data %r is sharing with us...' % corp) # now we fetch the urls we're allowed to pull from this corporation response = client.get( urlparse.urljoin(corp.ecm_url, '/corp/share/allowed/')) data = crypto.aes_decrypt(session_secret, response.read()) allowed_urls = json.loads(data) if not allowed_urls: LOG.warning('%r is not sharing any data with us' % corp.corporationName) for url in allowed_urls: try: shared_data = SharedData.objects.get(url=url) LOG.debug('Fetching shared data %r...' % url) response = client.get( urlparse.urljoin(corp.ecm_url, shared_data.url)) raw_data = crypto.aes_decrypt(session_secret, response.read()) if response.info().getheader( 'content-type') == 'application/gzip-compressed': raw_data = zlib.decompress(raw_data) shared_data.call_handler(corp, json.loads(raw_data)) except SharedData.DoesNotExist: LOG.error('Unknown SharedData with url=%r' % url) except: LOG.exception('') LOG.debug('Ending secure session with %r...' % corp.ecm_url) # finally destroy our session info to be sure nobody will steal it :) client.get(urlparse.urljoin(corp.ecm_url, '/corp/auth/endsession/'))
def get_challenge(request): """ This function will check for the Http-Authorization: header in the request. If found, it will look in the db for a TrustedCorp that has the given public key fingerprint. Then, it will encode a randomly generated secret with the TrustedCorp's public key. Store the secret in the current session and send the encrypted secret back to the client. """ auth_string = request.META.get('HTTP_AUTHORIZATION', None) if auth_string is None: return HttpResponse('Missing Authorization header', status=http.UNAUTHORIZED) (auth_method, key_fingerprint) = auth_string.split(' ', 1) # RSA is not an official http auth method but who cares :D if not auth_method.upper() == 'RSA': return HttpResponseBadRequest( "Bad auth method: %r. Please use 'RSA'." % auth_method) key_fingerprint = key_fingerprint.strip() try: corp = Corporation.objects.get(key_fingerprint=key_fingerprint) except Corporation.DoesNotExist: return HttpResponse("Key fingerprint not found, we don't know you.", status=http.UNAUTHORIZED) if not corp.is_trusted: return HttpResponse('Your corporation is not trusted by our server.', status=http.UNAUTHORIZED) if AUTH_FINGERPRINT in request.session: if request.session[AUTH_FINGERPRINT] != key_fingerprint: # to avoid taking over another TrustedCorp's session, we flush all the data. request.session.flush() else: request.session.cycle_key() request.session.set_expiry(SESSION_LENGTH) # we store the key_fingerprint to tie this session to the TrustedCorp request.session[AUTH_FINGERPRINT] = key_fingerprint request.session[AUTH_SECRET] = crypto.generate_secret() encrypted_secret = crypto.rsa_encrypt(corp.public_key, request.session[AUTH_SECRET]) return HttpResponse(encrypted_secret)
def get_challenge(request): """ This function will check for the Http-Authorization: header in the request. If found, it will look in the db for a TrustedCorp that has the given public key fingerprint. Then, it will encode a randomly generated secret with the TrustedCorp's public key. Store the secret in the current session and send the encrypted secret back to the client. """ auth_string = request.META.get('HTTP_AUTHORIZATION', None) if auth_string is None: return HttpResponse('Missing Authorization header', status=http.UNAUTHORIZED) (auth_method, key_fingerprint) = auth_string.split(' ', 1) # RSA is not an official http auth method but who cares :D if not auth_method.upper() == 'RSA': return HttpResponseBadRequest("Bad auth method: %r. Please use 'RSA'." % auth_method) key_fingerprint = key_fingerprint.strip() try: corp = Corporation.objects.get(key_fingerprint=key_fingerprint) except Corporation.DoesNotExist: return HttpResponse("Key fingerprint not found, we don't know you.", status=http.UNAUTHORIZED) if not corp.is_trusted: return HttpResponse('Your corporation is not trusted by our server.', status=http.UNAUTHORIZED) if AUTH_FINGERPRINT in request.session: if request.session[AUTH_FINGERPRINT] != key_fingerprint: # to avoid taking over another TrustedCorp's session, we flush all the data. request.session.flush() else: request.session.cycle_key() request.session.set_expiry(SESSION_LENGTH) # we store the key_fingerprint to tie this session to the TrustedCorp request.session[AUTH_FINGERPRINT] = key_fingerprint request.session[AUTH_SECRET] = crypto.generate_secret() encrypted_secret = crypto.rsa_encrypt(corp.public_key, request.session[AUTH_SECRET]) return HttpResponse(encrypted_secret)
def update_one_corp(corp): my_corp = Corporation.objects.mine() auth_url = urlparse.urljoin(corp.ecm_url, '/corp/auth/startsession/') client = HttpClient() LOG.debug('Establishing secure data exchange with %r...' % corp.ecm_url) response = client.get(auth_url, headers={'Authorization': 'RSA %s' % my_corp.key_fingerprint}) cipher_txt_in = response.read() # we decrypt the response with our private key session_secret = crypto.rsa_decrypt(my_corp.private_key, cipher_txt_in) # and encrypt it back with the corp's public key cipher_txt_out = crypto.rsa_encrypt(corp.public_key, session_secret) # then send it to the server client.post(auth_url, cipher_txt_out) LOG.debug('Fetching which data %r is sharing with us...' % corp) # now we fetch the urls we're allowed to pull from this corporation response = client.get(urlparse.urljoin(corp.ecm_url, '/corp/share/allowed/')) data = crypto.aes_decrypt(session_secret, response.read()) allowed_urls = json.loads(data) if not allowed_urls: LOG.warning('%r is not sharing any data with us' % corp.corporationName) for url in allowed_urls: try: shared_data = SharedData.objects.get(url=url) LOG.debug('Fetching shared data %r...' % url) response = client.get(urlparse.urljoin(corp.ecm_url, shared_data.url)) raw_data = crypto.aes_decrypt(session_secret, response.read()) if response.info().getheader('content-type') == 'application/gzip-compressed': raw_data = zlib.decompress(raw_data) shared_data.call_handler(corp, json.loads(raw_data)) except SharedData.DoesNotExist: LOG.error('Unknown SharedData with url=%r' % url) except: LOG.exception('') LOG.debug('Ending secure session with %r...' % corp.ecm_url) # finally destroy our session info to be sure nobody will steal it :) client.get(urlparse.urljoin(corp.ecm_url, '/corp/auth/endsession/'))