From 934702f61f1cbdbf001ebb598c22c75efa247645 Mon Sep 17 00:00:00 2001 From: Markus Krogh Date: Fri, 2 Jun 2017 13:19:30 +0200 Subject: Django 1.11 compatible and cleaned up --- src/apps/changepw/__init__.py | 0 src/apps/changepw/eduroam.mobileconfig | 68 +++++ src/apps/changepw/models.py | 34 +++ src/apps/changepw/nordunet_change_password.py | 277 +++++++++++++++++++++ .../changepw/templates/changepw/change_other.html | 37 +++ .../templates/changepw/change_password.html | 54 ++++ .../templates/changepw/change_public_ssh_key.html | 45 ++++ src/apps/changepw/templates/changepw/index.html | 41 +++ .../templates/changepw/reset_password.html | 44 ++++ src/apps/changepw/tests.py | 23 ++ src/apps/changepw/urls.py | 13 + src/apps/changepw/views.py | 183 ++++++++++++++ 12 files changed, 819 insertions(+) create mode 100644 src/apps/changepw/__init__.py create mode 100644 src/apps/changepw/eduroam.mobileconfig create mode 100644 src/apps/changepw/models.py create mode 100644 src/apps/changepw/nordunet_change_password.py create mode 100644 src/apps/changepw/templates/changepw/change_other.html create mode 100644 src/apps/changepw/templates/changepw/change_password.html create mode 100644 src/apps/changepw/templates/changepw/change_public_ssh_key.html create mode 100644 src/apps/changepw/templates/changepw/index.html create mode 100644 src/apps/changepw/templates/changepw/reset_password.html create mode 100644 src/apps/changepw/tests.py create mode 100644 src/apps/changepw/urls.py create mode 100644 src/apps/changepw/views.py (limited to 'src/apps/changepw') diff --git a/src/apps/changepw/__init__.py b/src/apps/changepw/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/src/apps/changepw/eduroam.mobileconfig b/src/apps/changepw/eduroam.mobileconfig new file mode 100644 index 0000000..952c924 --- /dev/null +++ b/src/apps/changepw/eduroam.mobileconfig @@ -0,0 +1,68 @@ + + + + + PayloadContent + + + EAPClientConfiguration + + AcceptEAPTypes + + 25 + + EAPFASTProvisionPAC + + EAPFASTProvisionPACAnonymously + + EAPFASTUsePAC + + OuterIdentity + nordu-user@nordu.net + TLSAllowTrustExceptions + + TLSTrustedServerNames + + eduroam1.nordu.net + + UserName + eduroam-user + + EncryptionType + WPA + HIDDEN_NETWORK + + PayloadDescription + Configures wireless connectivity settings. + PayloadDisplayName + Wi-Fi (eduroam) + PayloadIdentifier + net.nordu.iphone.profile.wifi + PayloadOrganization + NORDUnet + PayloadType + com.apple.wifi.managed + PayloadUUID + 63622959-0DCB-413A-9C3C-515833E38891 + PayloadVersion + 1 + SSID_STR + eduroam + + + PayloadDescription + Configuration for eduroam at NORDUnet + PayloadDisplayName + Eduroam Profile + PayloadIdentifier + net.nordu.iphone.profile + PayloadOrganization + NORDUnet + PayloadType + Configuration + PayloadUUID + 4AD09534-1BC6-41CA-BC88-56149799781B + PayloadVersion + 1 + + diff --git a/src/apps/changepw/models.py b/src/apps/changepw/models.py new file mode 100644 index 0000000..24e0bec --- /dev/null +++ b/src/apps/changepw/models.py @@ -0,0 +1,34 @@ +from django import forms +import re + +class ChangePasswordForm(forms.Form): + new_password = forms.CharField(widget=forms.PasswordInput) + new_password_again = forms.CharField(widget=forms.PasswordInput) + + def clean(self): + ''' + Validate the password submitted. + ''' + cleaned_data = self.cleaned_data + # The two submitted strings need to match. + new_password = cleaned_data.get('new_password') + new_password_again = cleaned_data.get('new_password_again') + if new_password != new_password_again: + raise forms.ValidationError('The typed passwords do not \ +match.') + # Check that the length is at least 10 characters. + if not len(new_password) >= 10: + raise forms.ValidationError('Your password needs to be at \ +least 10 characters long. Currently %d characters.' % len(new_password)) + # The password needs to contain at least one upper and one lower case + # letter and three numbers or special characters. + if not re.search('[a-z]', new_password) or not re.search( + '[A-Z]', new_password): + raise forms.ValidationError('You need at least one upper \ +case letter and one lower case letter in your password.') + numbers = re.findall('\d', new_password) + specials = re.findall('[,.\[\]!@#$%^&*?_\(\)-]', new_password) + if (len(numbers)+len(specials)) < 3: + raise forms.ValidationError('You need at least three numbers or \ +special characters i.e. 1234567890,.][!@#$%^&*?_()-') + return cleaned_data diff --git a/src/apps/changepw/nordunet_change_password.py b/src/apps/changepw/nordunet_change_password.py new file mode 100644 index 0000000..8149483 --- /dev/null +++ b/src/apps/changepw/nordunet_change_password.py @@ -0,0 +1,277 @@ +# -*- coding: utf-8 -*- +""" +Created on Mon May 9 14:20:31 2011 + +@author: lundberg +Used in django-changepw (http://git.nordu.net/?p=django-changepw.git;a=summary). +""" + +from subprocess import call, Popen, PIPE +import pexpect +import ldap +from django.conf import settings + +SUFFIXES = ['', '/ppp', '/net', '/vpn'] + + +def _normalize_whitespace(s): + """ + Removes leading and ending whitespace from a string. + """ + return ' '.join(s.split()) + + +def check_kerberos_password(username, password): + """ + Tries to kinit with the username and password. + Returns True and kdestroys the ticket if the kinit succeded and returns + False otherwise. + """ + child = pexpect.spawn('kinit %s' % username) + result = child.expect(['Password', 'not found']) + if result is 0: + child.sendline(password) + result = child.expect([ + 'kinit: Password incorrect', + 'kinit: krb5_get_init_creds: salt type 3 not supported', # Missmatch of kerberos version between client and server + 'unknown', + pexpect.EOF]) + if result == 3: + call('kdestroy') + return True + return False + + +def duplicated_kerberos_password(suffix, _username, password): + """ + Checks all suffixes except the one provided, if the password can unlock + any pricipal True is returned else False. + """ + kerberos_uid = _username.split('@') + kerberos_uid[1] = kerberos_uid[1].upper() + suffixes = list(SUFFIXES) + suffixes.remove(suffix) + for suff in suffixes: + username = '%s@' % suff + if check_kerberos_password(username.join(kerberos_uid), password): + return True + return False + + +def change_nordunet_sso_pw(user, new_password): + """ + Changes the Kerberos and LDAP password for the user. + """ + ret = _change_kerberos_pw('', user.username, new_password) + if not ret: + ret = set_nordunet_ldap_pw_sasl(user) + return ret + + +def set_nordunet_ldap_pw_sasl(user): + """ + Sets the users ldap password to a pointer to a Kerberos principal. + """ + username = user.username.split('@')[0] + ldap_dn = 'uid=%s,ou=People,dc=nordu,dc=net' % username + l = _connect_ldap(user=settings.LDAP_USER, password=settings.LDAP_PASSWORD) + if l: + try: + mod_attrs = [(ldap.MOD_REPLACE, 'userPassword', str('{SASL}%s@NORDU.NET' % username))] + l.modify_s(ldap_dn, mod_attrs) + except ldap.LDAPError, e: + l.unbind() + return e.message + l.unbind() + else: + return 'Invalid LDAP credentials in settings.' + return 0 + + +def change_nordunet_ppp_pw(user, new_password): + """ + Uses a third party script to change a Kerberos password. + Returns the return value from the third party script. + + User needs to be employee at NORDUnet to run this. User has + affiliation employee@nordu.net. + """ + if user.is_staff: + return _change_kerberos_pw('/ppp', user.username, new_password) + else: + return 'You need to be a NORDUnet employee or member to use this.' + + +def change_nordunet_net_pw(user, new_password): + """ + Uses a third party script to change a Kerberos password. + Returns the return value from the third party script. + + User needs to be employee at NORDUnet to run this. If user has + affiliation employee@nordu.net is_staff flag is True. + """ + if user.is_staff: + return _change_kerberos_pw('/net', user.username, new_password) + else: + return 'You need to be a NORDUnet employee to use this.' + + +def change_nordunet_vpn_pw(user, new_password): + """ + Uses a third party script to change a Kerberos password. + Returns the return value from the third party script. + + User needs to be employee at NORDUnet to run this. If user has + affiliation employee@nordu.net is_staff flag is True. + """ + if user.is_staff: + return _change_kerberos_pw('/vpn', user.username, new_password) + else: + return 'You need to be a NORDUnet employee to use this.' + + +def _change_kerberos_pw(suffix, username, new_password): + kerberos_uid = username.split('@') + kerberos_uid[1] = kerberos_uid[1].upper() + if not duplicated_kerberos_password(suffix, username, new_password): + kerberos_uid = '%s%s@%s' % (kerberos_uid[0], suffix, kerberos_uid[1]) + p = Popen([settings.KERBEROS_SCRIPT], stdin=PIPE) + p.communicate('%s %s' % (kerberos_uid, new_password)) + return p.wait() + return 'You can\'t set the same password as your %s password.' % _pretty_suffixes(without=suffix) + + +def _pretty_suffixes(without=None): + if without is None: + suffixes = [s for s in SUFFIXES if s is not without] + else: + suffixes = list(SUFFIXES) + if '' in suffixes: + suffixes.remove('') + suffixes.append('SSO') + return ', '.join([s.upper().replace('/', '') for s in suffixes]) + + +def _validate_ssh_key(s): + """ + Tries to validate a string against the public ssh key format as in + RFC4253 and RFC4716. + + Checks that the string is in three parts separated by whitespace and that + the first part is in public_key_formats and the second part is a base64 + encoded string. + + Returns True if the string validates. + """ + import base64 + public_key_formats = ['ssh-dss', 'ssh-rsa', 'pgp-sign-rsa', 'pgp-sign-dss', 'ssh-ed25519'] + three_parts = s.split() + if three_parts[0] in public_key_formats and len(three_parts) in [2,3]: + try: + base64.b64decode(three_parts[1]) + except TypeError: + return False + else: + return False + return True + + +def _connect_ldap(server=None, user=None, password=None): + """ + Connects to an ldap server and binds with supplied user and password. + """ + _server = server or settings.LDAP_URL + l = ldap.initialize(_server) + if not _server.startswith("ldaps"): + l.start_tls_s() + try: + if user is None: + l.simple_bind_s() + else: + l.bind_s(user, password) + except ldap.INVALID_CREDENTIALS: + return False + return l + + +def set_public_ssh_key(user, ssh_keys): + """ + Sets the provided string(s) as the sshPublicKey attribute for the user. + User need to have affiliation employee@nordu.net to use this function. + """ + if user.is_staff: + valid_keys = [] + for ssh_key in ssh_keys.split('\n'): + ssh_key = _normalize_whitespace(ssh_key) + if ssh_key: + if _validate_ssh_key(ssh_key): + valid_keys.append(ssh_key) + else: + return '%s is not a valid SSH key.' % ssh_key + if valid_keys: + ldap_dn = user.username.split('@') + ldap_dn = 'uid=%s,ou=People,dc=nordu,dc=net' % ldap_dn[0] + l = _connect_ldap(user=settings.LDAP_USER, password=settings.LDAP_PASSWORD) + if l: + try: + # Ensure that objectClass ldapPublicKey is added to the user + mod_attrs = [(ldap.MOD_ADD, 'objectClass', 'ldapPublicKey')] + l.modify_s(ldap_dn, mod_attrs) + except ldap.TYPE_OR_VALUE_EXISTS: + pass + try: + # Add the new ssh keys + for key in valid_keys: + mod_attrs = [(ldap.MOD_ADD, 'sshPublicKey', str(key))] + l.modify_s(ldap_dn, mod_attrs) + except ldap.LDAPError, e: + l.unbind() + return e.message + l.unbind() + else: + return 'Invalid LDAP credentials in settings.' + else: + return 'You need to be a NORDUnet employee to use this.' + return 0 + + +def get_public_ssh_keys(user): + l = _connect_ldap() + if l: + uid = user.username.split('@')[0] + dn = "uid=%s,ou=People,dc=nordu,dc=net" % uid + try: + res = l.search_s(dn, ldap.SCOPE_SUBTREE, "(objectClass=person)")[0][1] + return res.get('sshPublicKey') + except (ldap.LDAPError, TypeError): + pass + return None + + +def del_public_ssh_key(user, ssh_key): + """ + Sets the provided string(s) as the sshPublicKey attribute for the user. + User need to have affiliation employee@nordu.net to use this function. + """ + if user.is_staff: + ldap_dn = user.username.split('@') + ldap_dn = 'uid=%s,ou=People,dc=nordu,dc=net' % ldap_dn[0] + l = _connect_ldap(user=settings.LDAP_USER, + password=settings.LDAP_PASSWORD) + if l: + try: + # Remove all previous ssh keys + try: + mod_attrs = [(ldap.MOD_DELETE, 'sshPublicKey', ssh_key)] + l.modify_s(ldap_dn, mod_attrs) + except ldap.NO_SUCH_ATTRIBUTE: + pass + except ldap.LDAPError, e: + l.unbind() + return e.message + l.unbind() + else: + return 'Invalid LDAP credentials in settings.' + else: + return 'You need to be a NORDUnet employee to use this.' + return 0 diff --git a/src/apps/changepw/templates/changepw/change_other.html b/src/apps/changepw/templates/changepw/change_other.html new file mode 100644 index 0000000..0979e84 --- /dev/null +++ b/src/apps/changepw/templates/changepw/change_other.html @@ -0,0 +1,37 @@ +{% extends "base.html" %} +{% block js %} +{% endblock %} +{% block title %}Update public SSH keys{% endblock %} +{% block content %} +

Update your public SSH keys

+{% if return_value == None %} +
{% csrf_token %} +

When pasting multiple ssh public keys remember to use new line or a blank line between keys.

+ + + + + + + + + + +
Paste your SSH public keys:
+ +
+
+{% else %} + {% if return_value == 0 %} +

Your public SSH keys was updated successfully.

+ {% else %} +

Something went wrong. Please contact an administrator.

+

Return code: {{ return_value }}

+ {% endif %} +{% endif %} +

+ Back
+ Log out +

+{% endblock %} + diff --git a/src/apps/changepw/templates/changepw/change_password.html b/src/apps/changepw/templates/changepw/change_password.html new file mode 100644 index 0000000..5017b4c --- /dev/null +++ b/src/apps/changepw/templates/changepw/change_password.html @@ -0,0 +1,54 @@ +{% extends "base.html" %} +{% load static %} +{% block js %} + + +{% endblock %} +{% block title %}Change {{ pwtype }} password{% endblock %} +{% block content %} +

Change {{ pwtype }} password

+{% if form %} +

When thinking of a new password you need to remember to use:

+ + +

+ {{ form.non_field_errors }} +

+
{% csrf_token %} + + + + + {% for field in form %} + + + + + + + {% endfor %} +
Username:{{ username }}{% if pwtype == "ppp" %}/ppp{% endif %}
{{ field.errors }}
{{ field.label_tag }}:{{ field }}
+ +
+ +{% else %} + {% if return_value == 0 %} +

Your {{ pwtype }} password was changed successfully.

+ {% else %} +

Something went wrong. Please contact an administrator.

+

Return code: {{ return_value }}

+ {% endif %} +{% endif %} +

+ Back
+ Log out +

+{% endblock %} diff --git a/src/apps/changepw/templates/changepw/change_public_ssh_key.html b/src/apps/changepw/templates/changepw/change_public_ssh_key.html new file mode 100644 index 0000000..0ad6533 --- /dev/null +++ b/src/apps/changepw/templates/changepw/change_public_ssh_key.html @@ -0,0 +1,45 @@ +{% extends "base.html" %} +{% block js %} +{% endblock %} +{% block title %}Update public SSH keys{% endblock %} +{% block content %} + +{% if return_value == 0 or return_value == None %} + {% if return_value == 0 %} +

Your public SSH keys where updated successfully.

+ {% endif %} + +

Your existing public SSH keys

+ + {% for key in ssh_keys %} + + + + + {% endfor %} +
{{ key }}
Delete
+

Update your public SSH keys

+
{% csrf_token %} + + + + + + + + + + +
Paste your SSH public keys (one key per line):
+ +
+
+{% else %} +

Something went wrong. Please contact an administrator.

+

Return code: {{ return_value }}

+{% endif %} +

+ Back
+ Log out +

+{% endblock %} diff --git a/src/apps/changepw/templates/changepw/index.html b/src/apps/changepw/templates/changepw/index.html new file mode 100644 index 0000000..12df371 --- /dev/null +++ b/src/apps/changepw/templates/changepw/index.html @@ -0,0 +1,41 @@ +{% extends "base.html" %} +{% block js %} +{% endblock %} +{% block title %}SSO Password Manager{% endblock %} +{% block content %} +

SSO Password Manager

+

+ Hello {{ full_name|capfirst }},
+ Welcome to the single sign on password manager site. +

+ + + + + + + + + + + +
Your usernames
SSO username:{{ username }}
eduroam username:{{ username }}/ppp
+ +

+Available actions:
+Change single sign on (SSO) password
+{% if user.is_staff %} + Change TACACS password
+{% endif %} +{% if user.is_active or user.is_staff %} + Change eduroam password
+{% endif %} +{% if user.is_staff %} + Update your public SSH keys
+ Configure eduroam on your iDevice +{% endif %} +

+ +

Log out

+{% endblock %} + diff --git a/src/apps/changepw/templates/changepw/reset_password.html b/src/apps/changepw/templates/changepw/reset_password.html new file mode 100644 index 0000000..c56b920 --- /dev/null +++ b/src/apps/changepw/templates/changepw/reset_password.html @@ -0,0 +1,44 @@ +{% extends "base.html" %} +{% block js %} +{% endblock %} +{% block title %}Reset eduroam password{% endblock %} +{% block content %} +

Reset eduroam password

+{% if not return_value %} + + + + + {% if new_password %} + + + + {% else %} + + + + + {% endif %} +
Username:{{ username }}/ppp
Password:{{ new_password }}
Password: +
+ {% csrf_token %} + +
+
+

+ + Guide to eduroam setup +

+{% else %} +

Something went wrong. Please contact an administrator.

+

Return code: {{ return_value }}

+{% endif %} + +

+ Back
+ Log out +

+{% endblock %} + diff --git a/src/apps/changepw/tests.py b/src/apps/changepw/tests.py new file mode 100644 index 0000000..2247054 --- /dev/null +++ b/src/apps/changepw/tests.py @@ -0,0 +1,23 @@ +""" +This file demonstrates two different styles of tests (one doctest and one +unittest). These will both pass when you run "manage.py test". + +Replace these with more appropriate tests for your application. +""" + +from django.test import TestCase + +class SimpleTest(TestCase): + def test_basic_addition(self): + """ + Tests that 1 + 1 always equals 2. + """ + self.failUnlessEqual(1 + 1, 2) + +__test__ = {"doctest": """ +Another way to test that 1 + 1 is equal to 2. + +>>> 1 + 1 == 2 +True +"""} + diff --git a/src/apps/changepw/urls.py b/src/apps/changepw/urls.py new file mode 100644 index 0000000..8983950 --- /dev/null +++ b/src/apps/changepw/urls.py @@ -0,0 +1,13 @@ +# This also imports the include function +from django.conf.urls import url + +from . import views + +urlpatterns = [ + url(r'^$', views.index, name='index'), + url(r'^changepw/(?P[-\w]+)$', views.change_password, name='changepw'), + url(r'^changeother$', views.change_other, name='changeother'), + url(r'^ideviceconf$', views.ideviceconf, name='ideviceconf'), + url(r'^changepublicsshkeys$', views.change_public_ssh_keys, name='changepublicsshkeys'), + url(r'^changepublicsshkeys/deletekey/(?P\d+)$', views.delete_public_ssh_key, name='deletepublicsshkey'), +] diff --git a/src/apps/changepw/views.py b/src/apps/changepw/views.py new file mode 100644 index 0000000..c3fb090 --- /dev/null +++ b/src/apps/changepw/views.py @@ -0,0 +1,183 @@ +from django.contrib.auth.decorators import login_required +from apps.changepw.models import ChangePasswordForm +from django.http import HttpResponse +from django.shortcuts import render +import random +import nordunet_change_password as pw + + +def _change_password(pwtype, user, new_password): + ''' + Use this to call your change password function. + ''' + if pwtype == 'sso': + ret = pw.change_nordunet_sso_pw(user, new_password) + elif pwtype == 'ppp': + ret = pw.change_nordunet_ppp_pw(user, new_password) + elif pwtype == 'net': + ret = pw.change_nordunet_net_pw(user, new_password) + elif pwtype == 'vpn': + ret = pw.change_nordunet_vpn_pw(user, new_password) + else: + ret = 'Could not change that password type.' + return ret + + +def _change_other(request, *args): + ''' + Use this to call your change function. + ''' + user = request.user + ssh_key = request.POST.get('ssh_key', None) + if ssh_key: + ret = pw.set_public_ssh_key(user, ssh_key) + else: + return 1 + return ret + + +def _get_username(request): + ''' + Returns the actual username from the Shibboleth uid. + request.user.username == username@domain.com + ''' + return request.user.username.split('@')[0] + + +def _generate_password(n, z=3): + ''' + Returns a psudo random string of lenght n in accordance to the NORDUnet + security standard. z is the number of non-letters to include. + ''' + letters = 'abcdefghijklmnopqrstuvwxyz' + others = '1234567890!#%&?+*-_.<>' + pw = [] + for i in range(0, n//2): + pw.append(random.choice(letters)) + pw.append(random.choice(letters.upper())) + random.shuffle(pw) + pw = pw[:n] + for i in random.sample(range(0, n-1), z): + pw[i] = random.choice(others) + return ''.join(pw) + + +@login_required() +def index(request): + ''' + Greets the user and presents the choices available. + ''' + username = _get_username(request) + try: + full_name = request.user.get_full_name() + except AttributeError: + full_name = username + return render(request, + 'changepw/index.html', + {'full_name': full_name, 'username': username}) + + +@login_required() +def change_password(request, pwtype): + ''' + If the user is authenticated and the form is valid the password + changing script will be run with the username and new password. + The function that changes the password has to be provided as func. + ''' + username = _get_username(request) + form = ChangePasswordForm(request.POST or None) + return_value = -1 + if request.method == 'POST': + if form.is_valid(): + new_password = form.cleaned_data['new_password'] + return_value = _change_password(pwtype, request.user, new_password) + form = None + return render(request, + 'changepw/change_password.html', + {'form': form, + 'username': username, + 'pwtype': pwtype, + 'return_value': return_value}) + + +@login_required() +def change_other(request, *args): + ''' + Just passes along the request so that something can be done for that user. + ''' + username = _get_username(request) + return_value = None + if request.method == 'POST': + return_value = _change_other(request, *args) + return render(request, + 'changepw/change_other.html', + {'username': username, 'return_value': return_value}) + + +@login_required() +def change_public_ssh_keys(request): + """ + Lets the user remove or add public SSH keys. + """ + if request.POST: + ssh_key = request.POST.get('ssh_key', None) + if ssh_key: + ret = pw.set_public_ssh_key(request.user, ssh_key) + else: + ret = 'No SSH key to add.' + ssh_keys = pw.get_public_ssh_keys(request.user) + return render(request, + 'changepw/change_public_ssh_key.html', + {'username': request.user.username, + 'ssh_keys': ssh_keys, + 'return_value': ret}) + else: + ssh_keys = pw.get_public_ssh_keys(request.user) + return render(request, + 'changepw/change_public_ssh_key.html', + {'username': request.user.username, + 'ssh_keys': ssh_keys, + 'return_value': None}) + + +@login_required() +def delete_public_ssh_key(request, key_number): + """ + Delete a public SSH key. + """ + ssh_keys = pw.get_public_ssh_keys(request.user) + ret = pw.del_public_ssh_key(request.user, ssh_keys[int(key_number)]) + ssh_keys = pw.get_public_ssh_keys(request.user) + return render(request, + 'changepw/change_public_ssh_key.html', + { + 'username': request.user.username, + 'ssh_keys': ssh_keys, + 'return_value': ret}) + +def _create_ieduroam_conf(user): + """ + Creates an xml config (http://www.apple.com/DTDs/PropertyList-1.0.dtd) for + iPhone, iPod Touch or Ipad that can be set by surfing to the URL. + + Should ultimately returned with + HttpResponse(conf, mimetype='application/x-apple-aspen-config') + """ + try: + f = open('/var/lib/django/sso/apps/changepw/eduroam.mobileconfig') + except IOError: + return 'Could not open boilerplate configuration.' + uid = user.username.split('@')[0] + s = ''.join(f.readlines()) + s = s.replace('nordu-user', '%s-pwman' % uid) + conf = s.replace('eduroam-user', '%s/ppp' % uid) + return conf + + +def ideviceconf(request): + """ + HACK + """ + user = request.user + conf = _create_ieduroam_conf(user) + return HttpResponse(conf, content_type='application/x-apple-aspen-config') -- cgit v1.1