From: Jouni Malinen
Date: Sat, 22 Feb 2025 18:12:35 +0000 (+0200)
Subject: HS 2.0 server: Remove example OSU SPP server
X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=3462d242a3d1cedf2d6e64a55ea60a1183ae089b;p=thirdparty%2Fhostap.git
HS 2.0 server: Remove example OSU SPP server
Passpoint spec v3.4 removed all OSU functionality. In practice, this
means that there is not going to any deployment or use of the OSU
technology in the future and as such, there is no need to maintain this
example OSU server implementation.
Signed-off-by: Jouni Malinen
---
diff --git a/hs20/server/.gitignore b/hs20/server/.gitignore
deleted file mode 100644
index fecb096c12..0000000000
--- a/hs20/server/.gitignore
+++ /dev/null
@@ -1 +0,0 @@
-hs20_spp_server
diff --git a/hs20/server/Makefile b/hs20/server/Makefile
deleted file mode 100644
index 0cab6d6b01..0000000000
--- a/hs20/server/Makefile
+++ /dev/null
@@ -1,42 +0,0 @@
-ALL=hs20_spp_server
-
-include ../../src/build.rules
-
-CFLAGS += -I../../src
-CFLAGS += -I../../src/utils
-CFLAGS += -I../../src/crypto
-
-LIBS += -lsqlite3
-
-# Using glibc < 2.17 requires -lrt for clock_gettime()
-LIBS += -lrt
-
-ifndef CONFIG_NO_GITVER
-# Add VERSION_STR postfix for builds from a git repository
-ifeq ($(wildcard ../../.git),../../.git)
-GITVER := $(shell git describe --dirty=+)
-ifneq ($(GITVER),)
-CFLAGS += -DGIT_VERSION_STR_POSTFIX=\"-$(GITVER)\"
-endif
-endif
-endif
-
-OBJS=spp_server.o
-OBJS += hs20_spp_server.o
-OBJS += ../../src/utils/xml-utils.o
-OBJS += ../../src/utils/base64.o
-OBJS += ../../src/utils/common.o
-OBJS += ../../src/utils/os_unix.o
-OBJS += ../../src/utils/wpa_debug.o
-OBJS += ../../src/crypto/md5-internal.o
-CFLAGS += $(shell xml2-config --cflags)
-LIBS += $(shell xml2-config --libs)
-OBJS += ../../src/utils/xml_libxml2.o
-
-_OBJS_VAR := OBJS
-include ../../src/objs.mk
-hs20_spp_server: $(OBJS)
- $(LDO) $(LDFLAGS) -o hs20_spp_server $(OBJS) $(LIBS)
-
-clean: common-clean
- rm -f core *~
diff --git a/hs20/server/ca/clean.sh b/hs20/server/ca/clean.sh
deleted file mode 100755
index c72dcbda45..0000000000
--- a/hs20/server/ca/clean.sh
+++ /dev/null
@@ -1,13 +0,0 @@
-#!/bin/sh
-
-for i in server-client server server-revoked user ocsp; do
- rm -f $i.csr $i.key $i.pem
-done
-
-rm -f openssl.cnf.tmp
-if [ -d demoCA ]; then
- rm -r demoCA
-fi
-rm -f ca.pem logo.asn1 logo.der server.der ocsp-server-cache.der
-rm -f my-openssl.cnf my-openssl-root.cnf
-#rm -r rootCA
diff --git a/hs20/server/ca/est-csrattrs.cnf b/hs20/server/ca/est-csrattrs.cnf
deleted file mode 100644
index b50ea00d0b..0000000000
--- a/hs20/server/ca/est-csrattrs.cnf
+++ /dev/null
@@ -1,17 +0,0 @@
-asn1 = SEQUENCE:attrs
-
-[attrs]
-#oid1 = OID:challengePassword
-attr1 = SEQUENCE:extreq
-oid2 = OID:sha256WithRSAEncryption
-
-[extreq]
-oid = OID:extensionRequest
-vals = SET:extreqvals
-
-[extreqvals]
-
-oid1 = OID:macAddress
-#oid2 = OID:imei
-#oid3 = OID:meid
-#oid4 = OID:DevId
diff --git a/hs20/server/ca/est-csrattrs.sh b/hs20/server/ca/est-csrattrs.sh
deleted file mode 100755
index 0b73a04082..0000000000
--- a/hs20/server/ca/est-csrattrs.sh
+++ /dev/null
@@ -1,4 +0,0 @@
-#!/bin/sh
-
-openssl asn1parse -genconf est-csrattrs.cnf -out est-csrattrs.der -oid hs20.oid
-base64 est-csrattrs.der > est-attrs.b64
diff --git a/hs20/server/ca/hs20.oid b/hs20/server/ca/hs20.oid
deleted file mode 100644
index a829ff29bf..0000000000
--- a/hs20/server/ca/hs20.oid
+++ /dev/null
@@ -1,7 +0,0 @@
-1.3.6.1.1.1.1.22 macAddress
-1.2.840.113549.1.9.14 extensionRequest
-1.3.6.1.4.1.40808.1.1.1 id-wfa-hotspot-friendlyName
-1.3.6.1.4.1.40808.1.1.2 id-kp-HS2.0Auth
-1.3.6.1.4.1.40808.1.1.3 imei
-1.3.6.1.4.1.40808.1.1.4 meid
-1.3.6.1.4.1.40808.1.1.5 DevId
diff --git a/hs20/server/ca/ocsp-req.sh b/hs20/server/ca/ocsp-req.sh
deleted file mode 100755
index 931a20696d..0000000000
--- a/hs20/server/ca/ocsp-req.sh
+++ /dev/null
@@ -1,11 +0,0 @@
-#!/bin/sh
-
-for i in *.pem; do
- echo "===[ $i ]==================="
- openssl ocsp -text -CAfile ca.pem -verify_other demoCA/cacert.pem -trust_other -issuer demoCA/cacert.pem -cert $i -url http://localhost:8888/
-
-# openssl ocsp -text -CAfile rootCA/cacert.pem -issuer demoCA/cacert.pem -cert $i -url http://localhost:8888/
-
-# openssl ocsp -text -CAfile rootCA/cacert.pem -verify_other demoCA/cacert.pem -trust_other -issuer demoCA/cacert.pem -cert $i -url http://localhost:8888/
-# openssl ocsp -text -CAfile rootCA/cacert.pem -VAfile ca.pem -trust_other -issuer demoCA/cacert.pem -cert $i -url http://localhost:8888/
-done
diff --git a/hs20/server/ca/ocsp-responder-ica.sh b/hs20/server/ca/ocsp-responder-ica.sh
deleted file mode 100755
index 116c6e1c3d..0000000000
--- a/hs20/server/ca/ocsp-responder-ica.sh
+++ /dev/null
@@ -1,3 +0,0 @@
-#!/bin/sh
-
-openssl ocsp -index demoCA/index.txt -port 8888 -nmin 5 -rsigner demoCA/cacert.pem -rkey demoCA/private/cakey-plain.pem -CA demoCA/cacert.pem -resp_no_certs -text
diff --git a/hs20/server/ca/ocsp-responder.sh b/hs20/server/ca/ocsp-responder.sh
deleted file mode 100755
index 620947d01a..0000000000
--- a/hs20/server/ca/ocsp-responder.sh
+++ /dev/null
@@ -1,3 +0,0 @@
-#!/bin/sh
-
-openssl ocsp -index demoCA/index.txt -port 8888 -nmin 5 -rsigner ocsp.pem -rkey ocsp.key -CA demoCA/cacert.pem -text -ignore_err
diff --git a/hs20/server/ca/ocsp-update-cache.sh b/hs20/server/ca/ocsp-update-cache.sh
deleted file mode 100755
index f2b23250ca..0000000000
--- a/hs20/server/ca/ocsp-update-cache.sh
+++ /dev/null
@@ -1,11 +0,0 @@
-#!/bin/sh
-
-# NOTE: You may need to replace 'localhost' with your OCSP server hostname.
-openssl ocsp \
- -no_nonce \
- -CAfile ca.pem \
- -verify_other demoCA/cacert.pem \
- -issuer demoCA/cacert.pem \
- -cert server.pem \
- -url http://localhost:8888/ \
- -respout ocsp-server-cache.der
diff --git a/hs20/server/ca/openssl-root.cnf b/hs20/server/ca/openssl-root.cnf
deleted file mode 100644
index 5bc50be1db..0000000000
--- a/hs20/server/ca/openssl-root.cnf
+++ /dev/null
@@ -1,125 +0,0 @@
-# OpenSSL configuration file for Hotspot 2.0 PKI (Root CA)
-
-HOME = .
-RANDFILE = $ENV::HOME/.rnd
-oid_section = new_oids
-
-[ new_oids ]
-
-#logotypeoid=1.3.6.1.5.5.7.1.12
-
-####################################################################
-[ ca ]
-default_ca = CA_default # The default ca section
-
-####################################################################
-[ CA_default ]
-
-dir = ./rootCA # Where everything is kept
-certs = $dir/certs # Where the issued certs are kept
-crl_dir = $dir/crl # Where the issued crl are kept
-database = $dir/index.txt # database index file.
-#unique_subject = no # Set to 'no' to allow creation of
- # several certificates with same subject
-new_certs_dir = $dir/newcerts # default place for new certs.
-
-certificate = $dir/cacert.pem # The CA certificate
-serial = $dir/serial # The current serial number
-crlnumber = $dir/crlnumber # the current crl number
- # must be commented out to leave a V1 CRL
-crl = $dir/crl.pem # The current CRL
-private_key = $dir/private/cakey.pem# The private key
-RANDFILE = $dir/private/.rand # private random number file
-
-x509_extensions = usr_cert # The extentions to add to the cert
-
-name_opt = ca_default # Subject Name options
-cert_opt = ca_default # Certificate field options
-
-default_days = 365 # how long to certify for
-default_crl_days= 30 # how long before next CRL
-default_md = default # use public key default MD
-preserve = no # keep passed DN ordering
-
-policy = policy_match
-
-# For the CA policy
-[ policy_match ]
-countryName = match
-stateOrProvinceName = optional
-organizationName = match
-organizationalUnitName = optional
-commonName = supplied
-emailAddress = optional
-
-[ policy_anything ]
-countryName = optional
-stateOrProvinceName = optional
-localityName = optional
-organizationName = optional
-organizationalUnitName = optional
-commonName = supplied
-emailAddress = optional
-
-####################################################################
-[ req ]
-default_bits = 2048
-default_keyfile = privkey.pem
-distinguished_name = req_distinguished_name
-attributes = req_attributes
-x509_extensions = v3_ca # The extentions to add to the self signed cert
-
-input_password = @PASSWORD@
-output_password = @PASSWORD@
-
-string_mask = utf8only
-
-[ req_distinguished_name ]
-countryName = Country Name (2 letter code)
-countryName_default = US
-countryName_min = 2
-countryName_max = 2
-
-localityName = Locality Name (eg, city)
-localityName_default = Tuusula
-
-0.organizationName = Organization Name (eg, company)
-0.organizationName_default = WFA Hotspot 2.0
-
-##organizationalUnitName = Organizational Unit Name (eg, section)
-#organizationalUnitName_default =
-#@OU@
-
-commonName = Common Name (e.g. server FQDN or YOUR name)
-#@CN@
-commonName_max = 64
-
-emailAddress = Email Address
-emailAddress_max = 64
-
-[ req_attributes ]
-
-[ v3_req ]
-
-# Extensions to add to a certificate request
-basicConstraints = CA:FALSE
-keyUsage = nonRepudiation, digitalSignature, keyEncipherment
-subjectAltName=DNS:example.com,DNS:another.example.com
-
-[ v3_ca ]
-
-# Hotspot 2.0 PKI requirements
-subjectKeyIdentifier=hash
-basicConstraints = critical,CA:true
-keyUsage = critical, cRLSign, keyCertSign
-
-[ crl_ext ]
-
-# issuerAltName=issuer:copy
-authorityKeyIdentifier=keyid:always
-
-[ v3_OCSP ]
-
-basicConstraints = CA:FALSE
-keyUsage = nonRepudiation, digitalSignature, keyEncipherment
-extendedKeyUsage = OCSPSigning
diff --git a/hs20/server/ca/openssl.cnf b/hs20/server/ca/openssl.cnf
deleted file mode 100644
index 6141013834..0000000000
--- a/hs20/server/ca/openssl.cnf
+++ /dev/null
@@ -1,200 +0,0 @@
-# OpenSSL configuration file for Hotspot 2.0 PKI (Intermediate CA)
-
-HOME = .
-RANDFILE = $ENV::HOME/.rnd
-oid_section = new_oids
-
-[ new_oids ]
-
-#logotypeoid=1.3.6.1.5.5.7.1.12
-
-####################################################################
-[ ca ]
-default_ca = CA_default # The default ca section
-
-####################################################################
-[ CA_default ]
-
-dir = ./demoCA # Where everything is kept
-certs = $dir/certs # Where the issued certs are kept
-crl_dir = $dir/crl # Where the issued crl are kept
-database = $dir/index.txt # database index file.
-#unique_subject = no # Set to 'no' to allow creation of
- # several certificates with same subject
-new_certs_dir = $dir/newcerts # default place for new certs.
-
-certificate = $dir/cacert.pem # The CA certificate
-serial = $dir/serial # The current serial number
-crlnumber = $dir/crlnumber # the current crl number
- # must be commented out to leave a V1 CRL
-crl = $dir/crl.pem # The current CRL
-private_key = $dir/private/cakey.pem# The private key
-RANDFILE = $dir/private/.rand # private random number file
-
-x509_extensions = ext_client # The extentions to add to the cert
-
-name_opt = ca_default # Subject Name options
-cert_opt = ca_default # Certificate field options
-
-# Extension copying option: use with caution.
-copy_extensions = copy
-
-default_days = 365 # how long to certify for
-default_crl_days= 30 # how long before next CRL
-default_md = default # use public key default MD
-preserve = no # keep passed DN ordering
-
-policy = policy_match
-
-# For the CA policy
-[ policy_match ]
-countryName = supplied
-stateOrProvinceName = optional
-organizationName = supplied
-organizationalUnitName = optional
-commonName = supplied
-emailAddress = optional
-
-[ policy_osu_server ]
-countryName = match
-stateOrProvinceName = optional
-organizationName = match
-organizationalUnitName = supplied
-commonName = supplied
-emailAddress = optional
-
-[ policy_anything ]
-countryName = optional
-stateOrProvinceName = optional
-localityName = optional
-organizationName = optional
-organizationalUnitName = optional
-commonName = supplied
-emailAddress = optional
-
-####################################################################
-[ req ]
-default_bits = 2048
-default_keyfile = privkey.pem
-distinguished_name = req_distinguished_name
-attributes = req_attributes
-x509_extensions = v3_ca # The extentions to add to the self signed cert
-
-input_password = @PASSWORD@
-output_password = @PASSWORD@
-
-string_mask = utf8only
-
-[ req_distinguished_name ]
-countryName = Country Name (2 letter code)
-countryName_default = FI
-countryName_min = 2
-countryName_max = 2
-
-localityName = Locality Name (eg, city)
-localityName_default = Tuusula
-
-0.organizationName = Organization Name (eg, company)
-0.organizationName_default = @DOMAIN@
-
-##organizationalUnitName = Organizational Unit Name (eg, section)
-#organizationalUnitName_default =
-#@OU@
-
-commonName = Common Name (e.g. server FQDN or YOUR name)
-#@CN@
-commonName_max = 64
-
-emailAddress = Email Address
-emailAddress_max = 64
-
-[ req_attributes ]
-
-[ v3_ca ]
-
-# Hotspot 2.0 PKI requirements
-subjectKeyIdentifier=hash
-authorityKeyIdentifier=keyid:always,issuer
-basicConstraints = critical, CA:true, pathlen:0
-keyUsage = critical, cRLSign, keyCertSign
-authorityInfoAccess = OCSP;URI:@OCSP_URI@
-# For SP intermediate CA
-#subjectAltName=critical,otherName:1.3.6.1.4.1.40808.1.1.1;UTF8String:engExample OSU
-#nameConstraints=permitted;DNS:.@DOMAIN@
-#1.3.6.1.5.5.7.1.12=ASN1:SEQUENCE:LogotypeExtn
-
-[ v3_osu_server ]
-
-basicConstraints = critical, CA:true, pathlen:0
-keyUsage = critical, keyEncipherment
-#@ALTNAME@
-
-#logotypeoid=ASN1:SEQUENCE:LogotypeExtn
-1.3.6.1.5.5.7.1.12=ASN1:SEQUENCE:LogotypeExtn
-[LogotypeExtn]
-communityLogos=EXP:0,SEQUENCE:LogotypeInfo
-[LogotypeInfo]
-# note: implicit tag converted to explicit for CHOICE
-direct=EXP:0,SEQUENCE:LogotypeData
-[LogotypeData]
-image=SEQUENCE:LogotypeImage
-[LogotypeImage]
-imageDetails=SEQUENCE:LogotypeDetails
-imageInfo=SEQUENCE:LogotypeImageInfo
-[LogotypeDetails]
-mediaType=IA5STRING:image/png
-logotypeHash=SEQUENCE:HashAlgAndValues
-logotypeURI=SEQUENCE:URI
-[HashAlgAndValues]
-value1=SEQUENCE:HashAlgAndValueSHA256
-#value2=SEQUENCE:HashAlgAndValueSHA1
-[HashAlgAndValueSHA256]
-hashAlg=SEQUENCE:sha256_alg
-hashValue=FORMAT:HEX,OCTETSTRING:@LOGO_HASH256@
-[HashAlgAndValueSHA1]
-hashAlg=SEQUENCE:sha1_alg
-hashValue=FORMAT:HEX,OCTETSTRING:@LOGO_HASH1@
-[sha256_alg]
-algorithm=OID:sha256
-[sha1_alg]
-algorithm=OID:sha1
-[URI]
-uri=IA5STRING:@LOGO_URI@
-[LogotypeImageInfo]
-# default value color(1), component optional
-#type=IMP:0,INTEGER:1
-fileSize=INTEGER:7549
-xSize=INTEGER:128
-ySize=INTEGER:80
-language=IMP:4,IA5STRING:zxx
-
-[ crl_ext ]
-
-# issuerAltName=issuer:copy
-authorityKeyIdentifier=keyid:always
-
-[ v3_OCSP ]
-
-basicConstraints = CA:FALSE
-keyUsage = nonRepudiation, digitalSignature, keyEncipherment
-extendedKeyUsage = OCSPSigning
-
-[ ext_client ]
-
-basicConstraints=CA:FALSE
-subjectKeyIdentifier=hash
-authorityKeyIdentifier=keyid,issuer
-authorityInfoAccess = OCSP;URI:@OCSP_URI@
-#@ALTNAME@
-extendedKeyUsage = clientAuth
-
-[ ext_server ]
-
-# Hotspot 2.0 PKI requirements
-basicConstraints=critical, CA:FALSE
-subjectKeyIdentifier=hash
-authorityKeyIdentifier=keyid,issuer
-authorityInfoAccess = OCSP;URI:@OCSP_URI@
-#@ALTNAME@
-extendedKeyUsage = critical, serverAuth
-keyUsage = critical, keyEncipherment
diff --git a/hs20/server/ca/setup.sh b/hs20/server/ca/setup.sh
deleted file mode 100755
index 78abcccff4..0000000000
--- a/hs20/server/ca/setup.sh
+++ /dev/null
@@ -1,209 +0,0 @@
-#!/bin/sh
-
-if [ -z "$OPENSSL" ]; then
- OPENSSL=openssl
-fi
-export OPENSSL_CONF=$PWD/openssl.cnf
-PASS=whatever
-if [ -z "$DOMAIN" ]; then
- DOMAIN=w1.fi
-fi
-COMPANY=w1.fi
-OPER_ENG="engw1.fi TESTING USE"
-OPER_FI="finw1.fi TESTIKÃYTTÃ"
-CNR="Hotspot 2.0 Trust Root CA - 99"
-CNO="ocsp.$DOMAIN"
-CNV="osu-revoked.$DOMAIN"
-CNOC="osu-client.$DOMAIN"
-OSU_SERVER_HOSTNAME="osu.$DOMAIN"
-DEBUG=0
-OCSP_URI="http://$CNO:8888/"
-LOGO_URI="http://osu.w1.fi/w1fi_logo.png"
-LOGO_HASH256="4532f7ec36424381617c03c6ce87b55a51d6e7177ffafda243cebf280a68954d"
-LOGO_HASH1="5e1d5085676eede6b02da14d31c523ec20ffba0b"
-
-# Command line overrides
-USAGE=$( cat < my-openssl-root.cnf
-
-cat openssl.cnf | sed "s/@PASSWORD@/$PASS/" |
-sed "s,@OCSP_URI@,$OCSP_URI," |
-sed "s,@LOGO_URI@,$LOGO_URI," |
-sed "s,@LOGO_HASH1@,$LOGO_HASH1," |
-sed "s,@LOGO_HASH256@,$LOGO_HASH256," |
-sed "s/@DOMAIN@/$DOMAIN/" \
- > my-openssl.cnf
-
-
-cat my-openssl-root.cnf | sed "s/#@CN@/commonName_default = $CNR/" > openssl.cnf.tmp
-mkdir -p rootCA/certs rootCA/crl rootCA/newcerts rootCA/private
-touch rootCA/index.txt
-if [ -e rootCA/private/cakey.pem ]; then
- echo " * Use existing Root CA"
-else
- echo " * Generate Root CA private key"
- $OPENSSL req -config openssl.cnf.tmp -batch -new -newkey rsa:4096 -keyout rootCA/private/cakey.pem -out rootCA/careq.pem || fail "Failed to generate Root CA private key"
- echo " * Sign Root CA certificate"
- $OPENSSL ca -config openssl.cnf.tmp -md sha256 -create_serial -out rootCA/cacert.pem -days 10957 -batch -keyfile rootCA/private/cakey.pem -passin pass:$PASS -selfsign -extensions v3_ca -outdir rootCA/newcerts -infiles rootCA/careq.pem || fail "Failed to sign Root CA certificate"
- $OPENSSL x509 -in rootCA/cacert.pem -out rootCA/cacert.der -outform DER || fail "Failed to create rootCA DER"
- sha256sum rootCA/cacert.der > rootCA/cacert.fingerprint || fail "Failed to create rootCA fingerprint"
-fi
-if [ ! -e rootCA/crlnumber ]; then
- echo 00 > rootCA/crlnumber
-fi
-
-echo
-echo "---[ Intermediate CA ]--------------------------------------------------"
-echo
-
-cat my-openssl.cnf | sed "s/#@CN@/commonName_default = $COMPANY Hotspot 2.0 Intermediate CA/" > openssl.cnf.tmp
-mkdir -p demoCA/certs demoCA/crl demoCA/newcerts demoCA/private
-touch demoCA/index.txt
-if [ -e demoCA/private/cakey.pem ]; then
- echo " * Use existing Intermediate CA"
-else
- echo " * Generate Intermediate CA private key"
- $OPENSSL req -config openssl.cnf.tmp -batch -new -newkey rsa:2048 -keyout demoCA/private/cakey.pem -out demoCA/careq.pem || fail "Failed to generate Intermediate CA private key"
- echo " * Sign Intermediate CA certificate"
- $OPENSSL ca -config openssl.cnf.tmp -md sha256 -create_serial -out demoCA/cacert.pem -days 3652 -batch -keyfile rootCA/private/cakey.pem -cert rootCA/cacert.pem -passin pass:$PASS -extensions v3_ca -infiles demoCA/careq.pem || fail "Failed to sign Intermediate CA certificate"
- # horrible from security view point, but for testing purposes since OCSP responder does not seem to support -passin
- openssl rsa -in demoCA/private/cakey.pem -out demoCA/private/cakey-plain.pem -passin pass:$PASS
- $OPENSSL x509 -in demoCA/cacert.pem -out demoCA/cacert.der -outform DER || fail "Failed to create demoCA DER."
- sha256sum demoCA/cacert.der > demoCA/cacert.fingerprint || fail "Failed to create demoCA fingerprint"
-fi
-if [ ! -e demoCA/crlnumber ]; then
- echo 00 > demoCA/crlnumber
-fi
-
-echo
-echo "OCSP responder"
-echo
-
-cat my-openssl.cnf | sed "s/#@CN@/commonName_default = $CNO/" > openssl.cnf.tmp
-$OPENSSL req -config $PWD/openssl.cnf.tmp -batch -new -newkey rsa:2048 -nodes -out ocsp.csr -keyout ocsp.key -extensions v3_OCSP
-$OPENSSL ca -config $PWD/openssl.cnf.tmp -batch -md sha256 -keyfile demoCA/private/cakey.pem -passin pass:$PASS -in ocsp.csr -out ocsp.pem -days 730 -extensions v3_OCSP || fail "Could not generate ocsp.pem"
-
-echo
-echo "---[ Server - to be revoked ] ------------------------------------------"
-echo
-
-cat my-openssl.cnf | sed "s/#@CN@/commonName_default = $CNV/" > openssl.cnf.tmp
-$OPENSSL req -config $PWD/openssl.cnf.tmp -batch -new -newkey rsa:2048 -nodes -out server-revoked.csr -keyout server-revoked.key
-$OPENSSL ca -config $PWD/openssl.cnf.tmp -batch -md sha256 -in server-revoked.csr -out server-revoked.pem -key $PASS -days 730 -extensions ext_server
-$OPENSSL ca -revoke server-revoked.pem -key $PASS
-
-echo
-echo "---[ Server - with client ext key use ] ---------------------------------"
-echo "---[ Only used for negative-testing for OSU-client implementation ] -----"
-echo
-
-cat my-openssl.cnf | sed "s/#@CN@/commonName_default = $CNOC/" > openssl.cnf.tmp
-$OPENSSL req -config $PWD/openssl.cnf.tmp -batch -new -newkey rsa:2048 -nodes -out server-client.csr -keyout server-client.key || fail "Could not create server-client.key"
-$OPENSSL ca -config $PWD/openssl.cnf.tmp -batch -md sha256 -in server-client.csr -out server-client.pem -key $PASS -days 730 -extensions ext_client || fail "Could not create server-client.pem"
-
-echo
-echo "---[ User ]-------------------------------------------------------------"
-echo
-
-cat my-openssl.cnf | sed "s/#@CN@/commonName_default = User/" > openssl.cnf.tmp
-$OPENSSL req -config $PWD/openssl.cnf.tmp -batch -new -newkey rsa:2048 -nodes -out user.csr -keyout user.key || fail "Could not create user.key"
-$OPENSSL ca -config $PWD/openssl.cnf.tmp -batch -md sha256 -in user.csr -out user.pem -key $PASS -days 730 -extensions ext_client || fail "Could not create user.pem"
-
-echo
-echo "---[ Server ]-----------------------------------------------------------"
-echo
-
-ALT="DNS:$OSU_SERVER_HOSTNAME"
-ALT="$ALT,otherName:1.3.6.1.4.1.40808.1.1.1;UTF8String:$OPER_ENG"
-ALT="$ALT,otherName:1.3.6.1.4.1.40808.1.1.1;UTF8String:$OPER_FI"
-
-cat my-openssl.cnf |
- sed "s/#@CN@/commonName_default = $OSU_SERVER_HOSTNAME/" |
- sed "s/^##organizationalUnitName/organizationalUnitName/" |
- sed "s/#@OU@/organizationalUnitName_default = Hotspot 2.0 Online Sign Up Server/" |
- sed "s/#@ALTNAME@/subjectAltName=critical,$ALT/" \
- > openssl.cnf.tmp
-echo $OPENSSL req -config $PWD/openssl.cnf.tmp -batch -sha256 -new -newkey rsa:2048 -nodes -out server.csr -keyout server.key -reqexts v3_osu_server
-$OPENSSL req -config $PWD/openssl.cnf.tmp -batch -sha256 -new -newkey rsa:2048 -nodes -out server.csr -keyout server.key -reqexts v3_osu_server || fail "Failed to generate server request"
-$OPENSSL ca -config $PWD/openssl.cnf.tmp -batch -md sha256 -in server.csr -out server.pem -key $PASS -days 730 -extensions ext_server -policy policy_osu_server || fail "Failed to sign server certificate"
-
-#dump logotype details for debugging
-$OPENSSL x509 -in server.pem -out server.der -outform DER
-openssl asn1parse -in server.der -inform DER | grep HEX | tail -1 | sed 's/.*://' | xxd -r -p > logo.der
-openssl asn1parse -in logo.der -inform DER > logo.asn1
-
-
-echo
-echo "---[ CRL ]---------------------------------------------------------------"
-echo
-
-$OPENSSL ca -config $PWD/my-openssl.cnf -gencrl -md sha256 -out demoCA/crl/crl.pem -passin pass:$PASS
-
-echo
-echo "---[ Verify ]------------------------------------------------------------"
-echo
-
-$OPENSSL verify -CAfile rootCA/cacert.pem demoCA/cacert.pem
-$OPENSSL verify -CAfile rootCA/cacert.pem -untrusted demoCA/cacert.pem *.pem
-
-cat rootCA/cacert.pem demoCA/cacert.pem > ca.pem
diff --git a/hs20/server/ca/w1fi_logo.png b/hs20/server/ca/w1fi_logo.png
deleted file mode 100644
index ac7c259fff..0000000000
Binary files a/hs20/server/ca/w1fi_logo.png and /dev/null differ
diff --git a/hs20/server/hs20-osu-server.txt b/hs20/server/hs20-osu-server.txt
deleted file mode 100644
index 22478ad9d2..0000000000
--- a/hs20/server/hs20-osu-server.txt
+++ /dev/null
@@ -1,262 +0,0 @@
-Hotspot 2.0 OSU server
-======================
-
-The information in this document is based on the assumption that Ubuntu
-16.04 server (64-bit) distribution is used and the web server is
-Apache2. Neither of these are requirements for the installation, but if
-other combinations are used, the package names and configuration
-parameters may need to be adjusted.
-
-NOTE: This implementation and the example configuration here is meant
-only for testing purposes in a lab environment. This design is not
-secure to be installed in a publicly available Internet server without
-considerable amount of modification and review for security issues.
-
-
-Build dependencies
-------------------
-
-Ubuntu 16.04 server
-- default installation
-- upgraded to latest package versions
- sudo apt-get update
- sudo apt-get upgrade
-
-Packages needed for running the service:
- sudo apt-get install sqlite3
- sudo apt-get install apache2
- sudo apt-get install php-sqlite3 php-xml libapache2-mod-php
-
-Additional packages needed for building the components:
- sudo apt-get install build-essential
- sudo apt-get install libsqlite3-dev
- sudo apt-get install libssl-dev
- sudo apt-get install libxml2-dev
-
-
-Installation location
----------------------
-
-Select a location for the installation root directory. The example here
-assumes /home/user/hs20-server to be used, but this can be changed by
-editing couple of files as indicated below.
-
-sudo mkdir -p /home/user/hs20-server
-sudo chown $USER /home/user/hs20-server
-mkdir -p /home/user/hs20-server/spp
-mkdir -p /home/user/hs20-server/AS
-
-
-Build
------
-
-# hostapd as RADIUS server
-cd hostapd
-
-#example build configuration
-cat > .config < /home/user/hs20-server/terms-and-conditions <Terms and conditions..
-EOF
-
-# Build local keys and certs
-cd ca
-# Display help options.
-./setup.sh -h
-
-# Remove old keys, fill in appropriate values, and generate your keys.
-# For instance:
-./clean.sh
-rm -fr rootCA"
-old_hostname=myserver.local
-./setup.sh -C "Hotspot 2.0 Trust Root CA - CT" \
- -o $old_hostname-osu-client \
- -O $old_hostname-oscp -p lanforge -S $old_hostname \
- -V $old_hostname-osu-revoked \
- -m local -u http://$old_hostname:8888/
-
-# Configure subscription policies
-mkdir -p /home/user/hs20-server/spp/policy
-cat > /home/user/hs20-server/spp/policy/default.xml <
-
- 30
- ClientInitiated
- Unrestricted
- https://policy-server.osu.example.com/hs20/spp.php
-
-
-EOF
-
-
-# Install Hotspot 2.0 SPP and OMA DM XML schema/DTD files
-
-# XML schema for SPP
-# Copy the latest XML schema into /home/user/hs20-server/spp/spp.xsd
-
-# OMA DM Device Description Framework DTD
-# Copy into /home/user/hs20-server/spp/dm_ddf-v1_2.dtd
-# http://www.openmobilealliance.org/tech/DTD/dm_ddf-v1_2.dtd
-
-
-# Configure RADIUS authentication service
-# Note: Change the URL to match the setup
-# Note: Install AAA server key/certificate and root CA in Key directory
-
-cat > /home/user/hs20-server/AS/as-sql.conf < /home/user/hs20-server/AS/as.radius_clients <
- Options Indexes MultiViews FollowSymLinks
- AllowOverride None
- Require all granted
- SSLOptions +StdEnvVars
-
-
-Update SSL configuration to use the OSU server certificate/key.
-They keys and certs are called 'server.key' and 'server.pem' from
-ca/setup.sh.
-
-To support subscription remediation using client certificates, set
-"SSLVerifyClient optional" and configure the trust root CA(s) for the
-client certificates with SSLCACertificateFile.
-
-Enable default-ssl site and restart Apache2:
- sudo a2ensite default-ssl
- sudo a2enmod ssl
- sudo service apache2 restart
-
-
-Management UI
--------------
-
-The sample PHP scripts include a management UI for testing
-purposes. That is available at https:///hs20/users.php
-
-
-AP configuration
-----------------
-
-APs can now be configured to use the OSU server as the RADIUS
-authentication server. In addition, the OSU Provider List ANQP element
-should be configured to use the SPP (SOAP+XML) option and with the
-following Server URL:
-https:///hs20/spp.php/signup?realm=example.com
diff --git a/hs20/server/hs20_spp_server.c b/hs20/server/hs20_spp_server.c
deleted file mode 100644
index 347c40a73d..0000000000
--- a/hs20/server/hs20_spp_server.c
+++ /dev/null
@@ -1,207 +0,0 @@
-/*
- * Hotspot 2.0 SPP server - standalone version
- * Copyright (c) 2012-2013, Qualcomm Atheros, Inc.
- *
- * This software may be distributed under the terms of the BSD license.
- * See README for more details.
- */
-
-#include "includes.h"
-#include
-#include
-
-#include "common.h"
-#include "common/version.h"
-#include "xml-utils.h"
-#include "spp_server.h"
-
-
-static void write_timestamp(FILE *f)
-{
- time_t t;
- struct tm *tm;
-
- time(&t);
- tm = localtime(&t);
-
- fprintf(f, "%04u-%02u-%02u %02u:%02u:%02u ",
- tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday,
- tm->tm_hour, tm->tm_min, tm->tm_sec);
-}
-
-
-void debug_print(struct hs20_svc *ctx, int print, const char *fmt, ...)
-{
- va_list ap;
-
- if (ctx->debug_log == NULL)
- return;
-
- write_timestamp(ctx->debug_log);
- va_start(ap, fmt);
- vfprintf(ctx->debug_log, fmt, ap);
- va_end(ap);
-
- fprintf(ctx->debug_log, "\n");
-}
-
-
-void debug_dump_node(struct hs20_svc *ctx, const char *title, xml_node_t *node)
-{
- char *str;
-
- if (ctx->debug_log == NULL)
- return;
- str = xml_node_to_str(ctx->xml, node);
- if (str == NULL)
- return;
-
- write_timestamp(ctx->debug_log);
- fprintf(ctx->debug_log, "%s: '%s'\n", title, str);
- os_free(str);
-}
-
-
-static int process(struct hs20_svc *ctx)
-{
- int dmacc = 0;
- xml_node_t *soap, *spp, *resp;
- char *user, *realm, *post, *str;
-
- ctx->addr = getenv("HS20ADDR");
- if (ctx->addr)
- debug_print(ctx, 1, "Connection from %s", ctx->addr);
- ctx->test = getenv("HS20TEST");
- if (ctx->test)
- debug_print(ctx, 1, "Requested test functionality: %s",
- ctx->test);
-
- user = getenv("HS20USER");
- if (user && strlen(user) == 0)
- user = NULL;
- realm = getenv("HS20REALM");
- if (realm == NULL) {
- debug_print(ctx, 1, "HS20REALM not set");
- return -1;
- }
- post = getenv("HS20POST");
- if (post == NULL) {
- debug_print(ctx, 1, "HS20POST not set");
- return -1;
- }
-
- ctx->imsi = getenv("HS20IMSI");
- if (ctx->imsi)
- debug_print(ctx, 1, "IMSI %s", ctx->imsi);
-
- ctx->eap_method = getenv("HS20EAPMETHOD");
- if (ctx->eap_method)
- debug_print(ctx, 1, "EAP method %s", ctx->eap_method);
-
- ctx->id_hash = getenv("HS20IDHASH");
- if (ctx->id_hash)
- debug_print(ctx, 1, "ID-HASH %s", ctx->id_hash);
-
- soap = xml_node_from_buf(ctx->xml, post);
- if (soap == NULL) {
- debug_print(ctx, 1, "Could not parse SOAP data");
- return -1;
- }
- debug_dump_node(ctx, "Received SOAP message", soap);
- spp = soap_get_body(ctx->xml, soap);
- if (spp == NULL) {
- debug_print(ctx, 1, "Could not get SPP message");
- xml_node_free(ctx->xml, soap);
- return -1;
- }
- debug_dump_node(ctx, "Received SPP message", spp);
-
- resp = hs20_spp_server_process(ctx, spp, user, realm, dmacc);
- xml_node_free(ctx->xml, soap);
- if (resp == NULL && user == NULL) {
- debug_print(ctx, 1, "Request HTTP authentication");
- return 2; /* Request authentication */
- }
- if (resp == NULL) {
- debug_print(ctx, 1, "No response");
- return -1;
- }
-
- soap = soap_build_envelope(ctx->xml, resp);
- if (soap == NULL) {
- debug_print(ctx, 1, "SOAP envelope building failed");
- return -1;
- }
- str = xml_node_to_str(ctx->xml, soap);
- xml_node_free(ctx->xml, soap);
- if (str == NULL) {
- debug_print(ctx, 1, "Could not get node string");
- return -1;
- }
- printf("%s", str);
- free(str);
-
- return 0;
-}
-
-
-static void usage(void)
-{
- printf("usage:\n"
- "hs20_spp_server -r [-f]\n");
-}
-
-
-int main(int argc, char *argv[])
-{
- struct hs20_svc ctx;
- int ret;
-
- os_memset(&ctx, 0, sizeof(ctx));
- for (;;) {
- int c = getopt(argc, argv, "f:r:v");
- if (c < 0)
- break;
- switch (c) {
- case 'f':
- if (ctx.debug_log)
- break;
- ctx.debug_log = fopen(optarg, "a");
- if (ctx.debug_log == NULL) {
- printf("Could not write to %s\n", optarg);
- return -1;
- }
- break;
- case 'r':
- ctx.root_dir = optarg;
- break;
- case 'v':
- printf("hs20_spp_server v%s\n", VERSION_STR);
- return 0;
- default:
- usage();
- return -1;
- }
- }
- if (ctx.root_dir == NULL) {
- usage();
- return -1;
- }
- ctx.xml = xml_node_init_ctx(&ctx, NULL);
- if (ctx.xml == NULL)
- return -1;
- if (hs20_spp_server_init(&ctx) < 0) {
- xml_node_deinit_ctx(ctx.xml);
- return -1;
- }
-
- ret = process(&ctx);
- debug_print(&ctx, 1, "process() --> %d", ret);
-
- xml_node_deinit_ctx(ctx.xml);
- hs20_spp_server_deinit(&ctx);
- if (ctx.debug_log)
- fclose(ctx.debug_log);
-
- return ret;
-}
diff --git a/hs20/server/spp_server.c b/hs20/server/spp_server.c
deleted file mode 100644
index 72694be6e8..0000000000
--- a/hs20/server/spp_server.c
+++ /dev/null
@@ -1,2936 +0,0 @@
-/*
- * Hotspot 2.0 SPP server
- * Copyright (c) 2012-2013, Qualcomm Atheros, Inc.
- *
- * This software may be distributed under the terms of the BSD license.
- * See README for more details.
- */
-
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-
-#include "common.h"
-#include "base64.h"
-#include "md5_i.h"
-#include "xml-utils.h"
-#include "spp_server.h"
-
-
-#define SPP_NS_URI "http://www.wi-fi.org/specifications/hotspot2dot0/v1.0/spp"
-
-#define URN_OMA_DM_DEVINFO "urn:oma:mo:oma-dm-devinfo:1.0"
-#define URN_OMA_DM_DEVDETAIL "urn:oma:mo:oma-dm-devdetail:1.0"
-#define URN_OMA_DM_DMACC "urn:oma:mo:oma-dm-dmacc:1.0"
-#define URN_HS20_PPS "urn:wfa:mo:hotspot2dot0-perprovidersubscription:1.0"
-
-
-/* TODO: timeout to expire sessions */
-
-enum hs20_session_operation {
- NO_OPERATION,
- UPDATE_PASSWORD,
- CONTINUE_SUBSCRIPTION_REMEDIATION,
- CONTINUE_POLICY_UPDATE,
- USER_REMEDIATION,
- SUBSCRIPTION_REGISTRATION,
- POLICY_REMEDIATION,
- POLICY_UPDATE,
- FREE_REMEDIATION,
- CLEAR_REMEDIATION,
- CERT_REENROLL,
-};
-
-
-static char * db_get_session_val(struct hs20_svc *ctx, const char *user,
- const char *realm, const char *session_id,
- const char *field);
-static char * db_get_osu_config_val(struct hs20_svc *ctx, const char *realm,
- const char *field);
-static xml_node_t * build_policy(struct hs20_svc *ctx, const char *user,
- const char *realm, int use_dmacc);
-static xml_node_t * spp_exec_get_certificate(struct hs20_svc *ctx,
- const char *session_id,
- const char *user,
- const char *realm,
- int add_est_user);
-
-
-static int db_add_session(struct hs20_svc *ctx,
- const char *user, const char *realm,
- const char *sessionid, const char *pw,
- const char *redirect_uri,
- enum hs20_session_operation operation,
- const u8 *mac_addr)
-{
- char *sql;
- int ret = 0;
- char addr[20];
-
- if (mac_addr)
- snprintf(addr, sizeof(addr), MACSTR, MAC2STR(mac_addr));
- else
- addr[0] = '\0';
- sql = sqlite3_mprintf("INSERT INTO sessions(timestamp,id,user,realm,"
- "operation,password,redirect_uri,mac_addr,test) "
- "VALUES "
- "(strftime('%%Y-%%m-%%d %%H:%%M:%%f','now'),"
- "%Q,%Q,%Q,%d,%Q,%Q,%Q,%Q)",
- sessionid, user ? user : "", realm ? realm : "",
- operation, pw ? pw : "",
- redirect_uri ? redirect_uri : "",
- addr, ctx->test);
- if (sql == NULL)
- return -1;
- debug_print(ctx, 1, "DB: %s", sql);
- if (sqlite3_exec(ctx->db, sql, NULL, NULL, NULL) != SQLITE_OK) {
- debug_print(ctx, 1, "Failed to add session entry into sqlite "
- "database: %s", sqlite3_errmsg(ctx->db));
- ret = -1;
- }
- sqlite3_free(sql);
- return ret;
-}
-
-
-static void db_update_session_password(struct hs20_svc *ctx, const char *user,
- const char *realm, const char *sessionid,
- const char *pw)
-{
- char *sql;
-
- sql = sqlite3_mprintf("UPDATE sessions SET password=%Q WHERE id=%Q AND "
- "user=%Q AND realm=%Q",
- pw, sessionid, user, realm);
- if (sql == NULL)
- return;
- debug_print(ctx, 1, "DB: %s", sql);
- if (sqlite3_exec(ctx->db, sql, NULL, NULL, NULL) != SQLITE_OK) {
- debug_print(ctx, 1, "Failed to update session password: %s",
- sqlite3_errmsg(ctx->db));
- }
- sqlite3_free(sql);
-}
-
-
-static void db_update_session_machine_managed(struct hs20_svc *ctx,
- const char *user,
- const char *realm,
- const char *sessionid,
- const int pw_mm)
-{
- char *sql;
-
- sql = sqlite3_mprintf("UPDATE sessions SET machine_managed=%Q WHERE id=%Q AND user=%Q AND realm=%Q",
- pw_mm ? "1" : "0", sessionid, user, realm);
- if (sql == NULL)
- return;
- debug_print(ctx, 1, "DB: %s", sql);
- if (sqlite3_exec(ctx->db, sql, NULL, NULL, NULL) != SQLITE_OK) {
- debug_print(ctx, 1,
- "Failed to update session machine_managed: %s",
- sqlite3_errmsg(ctx->db));
- }
- sqlite3_free(sql);
-}
-
-
-static void db_add_session_pps(struct hs20_svc *ctx, const char *user,
- const char *realm, const char *sessionid,
- xml_node_t *node)
-{
- char *str;
- char *sql;
-
- str = xml_node_to_str(ctx->xml, node);
- if (str == NULL)
- return;
- sql = sqlite3_mprintf("UPDATE sessions SET pps=%Q WHERE id=%Q AND "
- "user=%Q AND realm=%Q",
- str, sessionid, user, realm);
- free(str);
- if (sql == NULL)
- return;
- debug_print(ctx, 1, "DB: %s", sql);
- if (sqlite3_exec(ctx->db, sql, NULL, NULL, NULL) != SQLITE_OK) {
- debug_print(ctx, 1, "Failed to add session pps: %s",
- sqlite3_errmsg(ctx->db));
- }
- sqlite3_free(sql);
-}
-
-
-static void db_add_session_devinfo(struct hs20_svc *ctx, const char *sessionid,
- xml_node_t *node)
-{
- char *str;
- char *sql;
-
- str = xml_node_to_str(ctx->xml, node);
- if (str == NULL)
- return;
- sql = sqlite3_mprintf("UPDATE sessions SET devinfo=%Q WHERE id=%Q",
- str, sessionid);
- free(str);
- if (sql == NULL)
- return;
- debug_print(ctx, 1, "DB: %s", sql);
- if (sqlite3_exec(ctx->db, sql, NULL, NULL, NULL) != SQLITE_OK) {
- debug_print(ctx, 1, "Failed to add session devinfo: %s",
- sqlite3_errmsg(ctx->db));
- }
- sqlite3_free(sql);
-}
-
-
-static void db_add_session_devdetail(struct hs20_svc *ctx,
- const char *sessionid,
- xml_node_t *node)
-{
- char *str;
- char *sql;
-
- str = xml_node_to_str(ctx->xml, node);
- if (str == NULL)
- return;
- sql = sqlite3_mprintf("UPDATE sessions SET devdetail=%Q WHERE id=%Q",
- str, sessionid);
- free(str);
- if (sql == NULL)
- return;
- debug_print(ctx, 1, "DB: %s", sql);
- if (sqlite3_exec(ctx->db, sql, NULL, NULL, NULL) != SQLITE_OK) {
- debug_print(ctx, 1, "Failed to add session devdetail: %s",
- sqlite3_errmsg(ctx->db));
- }
- sqlite3_free(sql);
-}
-
-
-static void db_add_session_dmacc(struct hs20_svc *ctx, const char *sessionid,
- const char *username, const char *password)
-{
- char *sql;
-
- sql = sqlite3_mprintf("UPDATE sessions SET osu_user=%Q, osu_password=%Q WHERE id=%Q",
- username, password, sessionid);
- if (!sql)
- return;
- debug_print(ctx, 1, "DB: %s", sql);
- if (sqlite3_exec(ctx->db, sql, NULL, NULL, NULL) != SQLITE_OK) {
- debug_print(ctx, 1, "Failed to add session DMAcc: %s",
- sqlite3_errmsg(ctx->db));
- }
- sqlite3_free(sql);
-}
-
-
-static void db_add_session_eap_method(struct hs20_svc *ctx,
- const char *sessionid,
- const char *method)
-{
- char *sql;
-
- sql = sqlite3_mprintf("UPDATE sessions SET eap_method=%Q WHERE id=%Q",
- method, sessionid);
- if (!sql)
- return;
- debug_print(ctx, 1, "DB: %s", sql);
- if (sqlite3_exec(ctx->db, sql, NULL, NULL, NULL) != SQLITE_OK) {
- debug_print(ctx, 1, "Failed to add session EAP method: %s",
- sqlite3_errmsg(ctx->db));
- }
- sqlite3_free(sql);
-}
-
-
-static void db_add_session_id_hash(struct hs20_svc *ctx, const char *sessionid,
- const char *id_hash)
-{
- char *sql;
-
- sql = sqlite3_mprintf("UPDATE sessions SET mobile_identifier_hash=%Q WHERE id=%Q",
- id_hash, sessionid);
- if (!sql)
- return;
- debug_print(ctx, 1, "DB: %s", sql);
- if (sqlite3_exec(ctx->db, sql, NULL, NULL, NULL) != SQLITE_OK) {
- debug_print(ctx, 1, "Failed to add session ID hash: %s",
- sqlite3_errmsg(ctx->db));
- }
- sqlite3_free(sql);
-}
-
-
-static void db_remove_session(struct hs20_svc *ctx,
- const char *user, const char *realm,
- const char *sessionid)
-{
- char *sql;
-
- if (user == NULL || realm == NULL) {
- sql = sqlite3_mprintf("DELETE FROM sessions WHERE "
- "id=%Q", sessionid);
- } else {
- sql = sqlite3_mprintf("DELETE FROM sessions WHERE "
- "user=%Q AND realm=%Q AND id=%Q",
- user, realm, sessionid);
- }
- if (sql == NULL)
- return;
- debug_print(ctx, 1, "DB: %s", sql);
- if (sqlite3_exec(ctx->db, sql, NULL, NULL, NULL) != SQLITE_OK) {
- debug_print(ctx, 1, "Failed to delete session entry from "
- "sqlite database: %s", sqlite3_errmsg(ctx->db));
- }
- sqlite3_free(sql);
-}
-
-
-static void hs20_eventlog(struct hs20_svc *ctx,
- const char *user, const char *realm,
- const char *sessionid, const char *notes,
- const char *dump)
-{
- char *sql;
- char *user_buf = NULL, *realm_buf = NULL;
-
- debug_print(ctx, 1, "eventlog: %s", notes);
-
- if (user == NULL) {
- user_buf = db_get_session_val(ctx, NULL, NULL, sessionid,
- "user");
- user = user_buf;
- realm_buf = db_get_session_val(ctx, NULL, NULL, sessionid,
- "realm");
- realm = realm_buf;
- }
-
- sql = sqlite3_mprintf("INSERT INTO eventlog"
- "(user,realm,sessionid,timestamp,notes,dump,addr)"
- " VALUES (%Q,%Q,%Q,"
- "strftime('%%Y-%%m-%%d %%H:%%M:%%f','now'),"
- "%Q,%Q,%Q)",
- user, realm, sessionid, notes,
- dump ? dump : "", ctx->addr ? ctx->addr : "");
- free(user_buf);
- free(realm_buf);
- if (sql == NULL)
- return;
- if (sqlite3_exec(ctx->db, sql, NULL, NULL, NULL) != SQLITE_OK) {
- debug_print(ctx, 1, "Failed to add eventlog entry into sqlite "
- "database: %s", sqlite3_errmsg(ctx->db));
- }
- sqlite3_free(sql);
-}
-
-
-static void hs20_eventlog_node(struct hs20_svc *ctx,
- const char *user, const char *realm,
- const char *sessionid, const char *notes,
- xml_node_t *node)
-{
- char *str;
-
- if (node)
- str = xml_node_to_str(ctx->xml, node);
- else
- str = NULL;
- hs20_eventlog(ctx, user, realm, sessionid, notes, str);
- free(str);
-}
-
-
-static void db_update_mo_str(struct hs20_svc *ctx, const char *user,
- const char *realm, const char *name,
- const char *str)
-{
- char *sql;
- if (user == NULL || realm == NULL || name == NULL)
- return;
- sql = sqlite3_mprintf("UPDATE users SET %s=%Q WHERE identity=%Q AND realm=%Q AND (phase2=1 OR methods='TLS')",
- name, str, user, realm);
- if (sql == NULL)
- return;
- debug_print(ctx, 1, "DB: %s", sql);
- if (sqlite3_exec(ctx->db, sql, NULL, NULL, NULL) != SQLITE_OK) {
- debug_print(ctx, 1, "Failed to update user MO entry in sqlite "
- "database: %s", sqlite3_errmsg(ctx->db));
- }
- sqlite3_free(sql);
-}
-
-
-static void db_update_mo(struct hs20_svc *ctx, const char *user,
- const char *realm, const char *name, xml_node_t *mo)
-{
- char *str;
-
- str = xml_node_to_str(ctx->xml, mo);
- if (str == NULL)
- return;
-
- db_update_mo_str(ctx, user, realm, name, str);
- free(str);
-}
-
-
-static void add_text_node(struct hs20_svc *ctx, xml_node_t *parent,
- const char *name, const char *value)
-{
- xml_node_create_text(ctx->xml, parent, NULL, name, value ? value : "");
-}
-
-
-static void add_text_node_conf(struct hs20_svc *ctx, const char *realm,
- xml_node_t *parent, const char *name,
- const char *field)
-{
- char *val;
- val = db_get_osu_config_val(ctx, realm, field);
- xml_node_create_text(ctx->xml, parent, NULL, name, val ? val : "");
- os_free(val);
-}
-
-
-static void add_text_node_conf_corrupt(struct hs20_svc *ctx, const char *realm,
- xml_node_t *parent, const char *name,
- const char *field)
-{
- char *val;
-
- val = db_get_osu_config_val(ctx, realm, field);
- if (val) {
- size_t len;
-
- len = os_strlen(val);
- if (len > 0) {
- if (val[len - 1] == '0')
- val[len - 1] = '1';
- else
- val[len - 1] = '0';
- }
- }
- xml_node_create_text(ctx->xml, parent, NULL, name, val ? val : "");
- os_free(val);
-}
-
-
-static int new_password(char *buf, int buflen)
-{
- int i;
-
- if (buflen < 1)
- return -1;
- buf[buflen - 1] = '\0';
- if (os_get_random((unsigned char *) buf, buflen - 1) < 0)
- return -1;
-
- for (i = 0; i < buflen - 1; i++) {
- unsigned char val = buf[i];
- val %= 2 * 26 + 10;
- if (val < 26)
- buf[i] = 'a' + val;
- else if (val < 2 * 26)
- buf[i] = 'A' + val - 26;
- else
- buf[i] = '0' + val - 2 * 26;
- }
-
- return 0;
-}
-
-
-struct get_db_field_data {
- const char *field;
- char *value;
-};
-
-
-static int get_db_field(void *ctx, int argc, char *argv[], char *col[])
-{
- struct get_db_field_data *data = ctx;
- int i;
-
- for (i = 0; i < argc; i++) {
- if (os_strcmp(col[i], data->field) == 0 && argv[i]) {
- os_free(data->value);
- data->value = os_strdup(argv[i]);
- break;
- }
- }
-
- return 0;
-}
-
-
-static char * db_get_val(struct hs20_svc *ctx, const char *user,
- const char *realm, const char *field, int dmacc)
-{
- char *cmd;
- struct get_db_field_data data;
-
- cmd = sqlite3_mprintf("SELECT %s FROM users WHERE %s=%Q AND realm=%Q AND (phase2=1 OR methods='TLS')",
- field, dmacc ? "osu_user" : "identity",
- user, realm);
- if (cmd == NULL)
- return NULL;
- memset(&data, 0, sizeof(data));
- data.field = field;
- if (sqlite3_exec(ctx->db, cmd, get_db_field, &data, NULL) != SQLITE_OK)
- {
- debug_print(ctx, 1, "Could not find user '%s'", user);
- sqlite3_free(cmd);
- return NULL;
- }
- sqlite3_free(cmd);
-
- debug_print(ctx, 1, "DB: user='%s' realm='%s' field='%s' dmacc=%d --> "
- "value='%s'", user, realm, field, dmacc, data.value);
-
- return data.value;
-}
-
-
-static int db_update_val(struct hs20_svc *ctx, const char *user,
- const char *realm, const char *field,
- const char *val, int dmacc)
-{
- char *cmd;
- int ret;
-
- cmd = sqlite3_mprintf("UPDATE users SET %s=%Q WHERE %s=%Q AND realm=%Q AND (phase2=1 OR methods='TLS')",
- field, val, dmacc ? "osu_user" : "identity", user,
- realm);
- if (cmd == NULL)
- return -1;
- debug_print(ctx, 1, "DB: %s", cmd);
- if (sqlite3_exec(ctx->db, cmd, NULL, NULL, NULL) != SQLITE_OK) {
- debug_print(ctx, 1,
- "Failed to update user in sqlite database: %s",
- sqlite3_errmsg(ctx->db));
- ret = -1;
- } else {
- debug_print(ctx, 1,
- "DB: user='%s' realm='%s' field='%s' set to '%s'",
- user, realm, field, val);
- ret = 0;
- }
- sqlite3_free(cmd);
-
- return ret;
-}
-
-
-static char * db_get_session_val(struct hs20_svc *ctx, const char *user,
- const char *realm, const char *session_id,
- const char *field)
-{
- char *cmd;
- struct get_db_field_data data;
-
- if (user == NULL || realm == NULL) {
- cmd = sqlite3_mprintf("SELECT %s FROM sessions WHERE "
- "id=%Q", field, session_id);
- } else {
- cmd = sqlite3_mprintf("SELECT %s FROM sessions WHERE "
- "user=%Q AND realm=%Q AND id=%Q",
- field, user, realm, session_id);
- }
- if (cmd == NULL)
- return NULL;
- debug_print(ctx, 1, "DB: %s", cmd);
- memset(&data, 0, sizeof(data));
- data.field = field;
- if (sqlite3_exec(ctx->db, cmd, get_db_field, &data, NULL) != SQLITE_OK)
- {
- debug_print(ctx, 1, "DB: Could not find session %s: %s",
- session_id, sqlite3_errmsg(ctx->db));
- sqlite3_free(cmd);
- return NULL;
- }
- sqlite3_free(cmd);
-
- debug_print(ctx, 1, "DB: return '%s'", data.value);
- return data.value;
-}
-
-
-static int update_password(struct hs20_svc *ctx, const char *user,
- const char *realm, const char *pw, int dmacc)
-{
- char *cmd;
-
- cmd = sqlite3_mprintf("UPDATE users SET password=%Q, "
- "remediation='' "
- "WHERE %s=%Q AND phase2=1",
- pw, dmacc ? "osu_user" : "identity",
- user);
- if (cmd == NULL)
- return -1;
- debug_print(ctx, 1, "DB: %s", cmd);
- if (sqlite3_exec(ctx->db, cmd, NULL, NULL, NULL) != SQLITE_OK) {
- debug_print(ctx, 1, "Failed to update database for user '%s'",
- user);
- }
- sqlite3_free(cmd);
-
- return 0;
-}
-
-
-static int clear_remediation(struct hs20_svc *ctx, const char *user,
- const char *realm, int dmacc)
-{
- char *cmd;
-
- cmd = sqlite3_mprintf("UPDATE users SET remediation='' WHERE %s=%Q",
- dmacc ? "osu_user" : "identity",
- user);
- if (cmd == NULL)
- return -1;
- debug_print(ctx, 1, "DB: %s", cmd);
- if (sqlite3_exec(ctx->db, cmd, NULL, NULL, NULL) != SQLITE_OK) {
- debug_print(ctx, 1, "Failed to update database for user '%s'",
- user);
- }
- sqlite3_free(cmd);
-
- return 0;
-}
-
-
-static int add_eap_ttls(struct hs20_svc *ctx, xml_node_t *parent)
-{
- xml_node_t *node;
-
- node = xml_node_create(ctx->xml, parent, NULL, "EAPMethod");
- if (node == NULL)
- return -1;
-
- add_text_node(ctx, node, "EAPType", "21");
- add_text_node(ctx, node, "InnerMethod", "MS-CHAP-V2");
-
- return 0;
-}
-
-
-static xml_node_t * build_username_password(struct hs20_svc *ctx,
- xml_node_t *parent,
- const char *user, const char *pw)
-{
- xml_node_t *node;
- char *b64;
- size_t len;
-
- node = xml_node_create(ctx->xml, parent, NULL, "UsernamePassword");
- if (node == NULL)
- return NULL;
-
- add_text_node(ctx, node, "Username", user);
-
- b64 = base64_encode(pw, strlen(pw), NULL);
- if (b64 == NULL)
- return NULL;
- len = os_strlen(b64);
- if (len > 0 && b64[len - 1] == '\n')
- b64[len - 1] = '\0';
- add_text_node(ctx, node, "Password", b64);
- free(b64);
-
- return node;
-}
-
-
-static int add_username_password(struct hs20_svc *ctx, xml_node_t *cred,
- const char *user, const char *pw,
- int machine_managed)
-{
- xml_node_t *node;
-
- node = build_username_password(ctx, cred, user, pw);
- if (node == NULL)
- return -1;
-
- add_text_node(ctx, node, "MachineManaged",
- machine_managed ? "TRUE" : "FALSE");
- add_text_node(ctx, node, "SoftTokenApp", "");
- add_eap_ttls(ctx, node);
-
- return 0;
-}
-
-
-static void add_creation_date(struct hs20_svc *ctx, xml_node_t *cred)
-{
- char str[30];
- time_t now;
- struct tm tm;
-
- time(&now);
- gmtime_r(&now, &tm);
- snprintf(str, sizeof(str), "%04u-%02u-%02uT%02u:%02u:%02uZ",
- tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday,
- tm.tm_hour, tm.tm_min, tm.tm_sec);
- xml_node_create_text(ctx->xml, cred, NULL, "CreationDate", str);
-}
-
-
-static xml_node_t * build_credential_pw(struct hs20_svc *ctx,
- const char *user, const char *realm,
- const char *pw, int machine_managed)
-{
- xml_node_t *cred;
-
- cred = xml_node_create_root(ctx->xml, NULL, NULL, NULL, "Credential");
- if (cred == NULL) {
- debug_print(ctx, 1, "Failed to create Credential node");
- return NULL;
- }
- add_creation_date(ctx, cred);
- if (add_username_password(ctx, cred, user, pw, machine_managed) < 0) {
- xml_node_free(ctx->xml, cred);
- return NULL;
- }
- add_text_node(ctx, cred, "Realm", realm);
-
- return cred;
-}
-
-
-static xml_node_t * build_credential(struct hs20_svc *ctx,
- const char *user, const char *realm,
- char *new_pw, size_t new_pw_len)
-{
- if (new_password(new_pw, new_pw_len) < 0)
- return NULL;
- debug_print(ctx, 1, "Update password to '%s'", new_pw);
- return build_credential_pw(ctx, user, realm, new_pw, 1);
-}
-
-
-static xml_node_t * build_credential_cert(struct hs20_svc *ctx,
- const char *user, const char *realm,
- const char *cert_fingerprint)
-{
- xml_node_t *cred, *cert;
-
- cred = xml_node_create_root(ctx->xml, NULL, NULL, NULL, "Credential");
- if (cred == NULL) {
- debug_print(ctx, 1, "Failed to create Credential node");
- return NULL;
- }
- add_creation_date(ctx, cred);
- cert = xml_node_create(ctx->xml, cred, NULL, "DigitalCertificate");
- add_text_node(ctx, cert, "CertificateType", "x509v3");
- add_text_node(ctx, cert, "CertSHA256Fingerprint", cert_fingerprint);
- add_text_node(ctx, cred, "Realm", realm);
-
- return cred;
-}
-
-
-static xml_node_t * build_post_dev_data_response(struct hs20_svc *ctx,
- xml_namespace_t **ret_ns,
- const char *session_id,
- const char *status,
- const char *error_code)
-{
- xml_node_t *spp_node = NULL;
- xml_namespace_t *ns;
-
- spp_node = xml_node_create_root(ctx->xml, SPP_NS_URI, "spp", &ns,
- "sppPostDevDataResponse");
- if (spp_node == NULL)
- return NULL;
- if (ret_ns)
- *ret_ns = ns;
-
- xml_node_add_attr(ctx->xml, spp_node, ns, "sppVersion", "1.0");
- xml_node_add_attr(ctx->xml, spp_node, ns, "sessionID", session_id);
- xml_node_add_attr(ctx->xml, spp_node, ns, "sppStatus", status);
-
- if (error_code) {
- xml_node_t *node;
- node = xml_node_create(ctx->xml, spp_node, ns, "sppError");
- if (node)
- xml_node_add_attr(ctx->xml, node, NULL, "errorCode",
- error_code);
- }
-
- return spp_node;
-}
-
-
-static int add_update_node(struct hs20_svc *ctx, xml_node_t *spp_node,
- xml_namespace_t *ns, const char *uri,
- xml_node_t *upd_node)
-{
- xml_node_t *node, *tnds;
- char *str;
-
- tnds = mo_to_tnds(ctx->xml, upd_node, 0, NULL, NULL);
- if (!tnds)
- return -1;
-
- str = xml_node_to_str(ctx->xml, tnds);
- xml_node_free(ctx->xml, tnds);
- if (str == NULL)
- return -1;
- node = xml_node_create_text(ctx->xml, spp_node, ns, "updateNode", str);
- free(str);
-
- xml_node_add_attr(ctx->xml, node, ns, "managementTreeURI", uri);
-
- return 0;
-}
-
-
-static xml_node_t * read_subrem_file(struct hs20_svc *ctx,
- const char *subrem_id,
- char *uri, size_t uri_size)
-{
- char fname[200];
- char *buf, *buf2, *pos;
- size_t len;
- xml_node_t *node;
-
- os_snprintf(fname, sizeof(fname), "%s/spp/subrem/%s",
- ctx->root_dir, subrem_id);
- debug_print(ctx, 1, "Use subrem file %s", fname);
-
- buf = os_readfile(fname, &len);
- if (!buf)
- return NULL;
- buf2 = os_realloc(buf, len + 1);
- if (!buf2) {
- os_free(buf);
- return NULL;
- }
- buf = buf2;
- buf[len] = '\0';
-
- pos = os_strchr(buf, '\n');
- if (!pos) {
- os_free(buf);
- return NULL;
- }
- *pos++ = '\0';
- os_strlcpy(uri, buf, uri_size);
-
- node = xml_node_from_buf(ctx->xml, pos);
- os_free(buf);
-
- return node;
-}
-
-
-static xml_node_t * build_sub_rem_resp(struct hs20_svc *ctx,
- const char *user, const char *realm,
- const char *session_id,
- int machine_rem, int dmacc)
-{
- xml_namespace_t *ns;
- xml_node_t *spp_node, *cred;
- char buf[400];
- char new_pw[33];
- char *status;
- char *cert;
-
- cert = db_get_val(ctx, user, realm, "cert", dmacc);
- if (cert && cert[0] == '\0') {
- os_free(cert);
- cert = NULL;
- }
- if (cert) {
- char *subrem;
-
- /* No change needed in PPS MO unless specifically asked to */
- cred = NULL;
- buf[0] = '\0';
-
- subrem = db_get_val(ctx, user, realm, "subrem", dmacc);
- if (subrem && subrem[0]) {
- cred = read_subrem_file(ctx, subrem, buf, sizeof(buf));
- if (!cred) {
- debug_print(ctx, 1,
- "Could not create updateNode from subrem file");
- os_free(subrem);
- os_free(cert);
- return NULL;
- }
- }
- os_free(subrem);
- } else {
- char *real_user = NULL;
- char *pw;
-
- if (dmacc) {
- real_user = db_get_val(ctx, user, realm, "identity",
- dmacc);
- if (!real_user) {
- debug_print(ctx, 1,
- "Could not find user identity for dmacc user '%s'",
- user);
- return NULL;
- }
- }
-
- pw = db_get_session_val(ctx, user, realm, session_id,
- "password");
- if (pw && pw[0]) {
- debug_print(ctx, 1, "New password from the user: '%s'",
- pw);
- snprintf(new_pw, sizeof(new_pw), "%s", pw);
- free(pw);
- cred = build_credential_pw(ctx,
- real_user ? real_user : user,
- realm, new_pw, 0);
- } else {
- cred = build_credential(ctx,
- real_user ? real_user : user,
- realm, new_pw, sizeof(new_pw));
- }
-
- free(real_user);
- if (!cred) {
- debug_print(ctx, 1, "Could not build credential");
- os_free(cert);
- return NULL;
- }
-
- snprintf(buf, sizeof(buf),
- "./Wi-Fi/%s/PerProviderSubscription/Cred01/Credential",
- realm);
- }
-
- status = "Remediation complete, request sppUpdateResponse";
- spp_node = build_post_dev_data_response(ctx, &ns, session_id, status,
- NULL);
- if (spp_node == NULL) {
- debug_print(ctx, 1, "Could not build sppPostDevDataResponse");
- os_free(cert);
- return NULL;
- }
-
- if ((cred && add_update_node(ctx, spp_node, ns, buf, cred) < 0) ||
- (!cred && !xml_node_create(ctx->xml, spp_node, ns, "noMOUpdate"))) {
- debug_print(ctx, 1, "Could not add update node");
- xml_node_free(ctx->xml, spp_node);
- os_free(cert);
- return NULL;
- }
-
- hs20_eventlog_node(ctx, user, realm, session_id,
- machine_rem ? "machine remediation" :
- "user remediation", cred);
- xml_node_free(ctx->xml, cred);
-
- if (cert) {
- debug_print(ctx, 1, "Request DB remediation clearing on success notification (certificate credential)");
- db_add_session(ctx, user, realm, session_id, NULL, NULL,
- CLEAR_REMEDIATION, NULL);
- } else {
- debug_print(ctx, 1, "Request DB password update on success "
- "notification");
- db_add_session(ctx, user, realm, session_id, new_pw, NULL,
- UPDATE_PASSWORD, NULL);
- }
- os_free(cert);
-
- return spp_node;
-}
-
-
-static xml_node_t * machine_remediation(struct hs20_svc *ctx,
- const char *user,
- const char *realm,
- const char *session_id, int dmacc)
-{
- return build_sub_rem_resp(ctx, user, realm, session_id, 1, dmacc);
-}
-
-
-static xml_node_t * cert_reenroll(struct hs20_svc *ctx,
- const char *user,
- const char *realm,
- const char *session_id)
-{
- db_add_session(ctx, user, realm, session_id, NULL, NULL,
- CERT_REENROLL, NULL);
- return spp_exec_get_certificate(ctx, session_id, user, realm, 0);
-}
-
-
-static xml_node_t * policy_remediation(struct hs20_svc *ctx,
- const char *user, const char *realm,
- const char *session_id, int dmacc)
-{
- xml_namespace_t *ns;
- xml_node_t *spp_node, *policy;
- char buf[400];
- const char *status;
-
- hs20_eventlog(ctx, user, realm, session_id,
- "requires policy remediation", NULL);
-
- db_add_session(ctx, user, realm, session_id, NULL, NULL,
- POLICY_REMEDIATION, NULL);
-
- policy = build_policy(ctx, user, realm, dmacc);
- if (!policy) {
- return build_post_dev_data_response(
- ctx, NULL, session_id,
- "No update available at this time", NULL);
- }
-
- status = "Remediation complete, request sppUpdateResponse";
- spp_node = build_post_dev_data_response(ctx, &ns, session_id, status,
- NULL);
- if (spp_node == NULL)
- return NULL;
-
- snprintf(buf, sizeof(buf),
- "./Wi-Fi/%s/PerProviderSubscription/Cred01/Policy",
- realm);
-
- if (add_update_node(ctx, spp_node, ns, buf, policy) < 0) {
- xml_node_free(ctx->xml, spp_node);
- xml_node_free(ctx->xml, policy);
- return NULL;
- }
-
- hs20_eventlog_node(ctx, user, realm, session_id,
- "policy update (sub rem)", policy);
- xml_node_free(ctx->xml, policy);
-
- return spp_node;
-}
-
-
-static xml_node_t * browser_remediation(struct hs20_svc *ctx,
- const char *session_id,
- const char *redirect_uri,
- const char *uri)
-{
- xml_namespace_t *ns;
- xml_node_t *spp_node, *exec_node;
-
- if (redirect_uri == NULL) {
- debug_print(ctx, 1, "Missing redirectURI attribute for user "
- "remediation");
- return NULL;
- }
- debug_print(ctx, 1, "redirectURI %s", redirect_uri);
-
- spp_node = build_post_dev_data_response(ctx, &ns, session_id, "OK",
- NULL);
- if (spp_node == NULL)
- return NULL;
-
- exec_node = xml_node_create(ctx->xml, spp_node, ns, "exec");
- xml_node_create_text(ctx->xml, exec_node, ns, "launchBrowserToURI",
- uri);
- return spp_node;
-}
-
-
-static xml_node_t * user_remediation(struct hs20_svc *ctx, const char *user,
- const char *realm, const char *session_id,
- const char *redirect_uri)
-{
- char uri[300], *val;
-
- hs20_eventlog(ctx, user, realm, session_id,
- "requires user remediation", NULL);
- val = db_get_osu_config_val(ctx, realm, "remediation_url");
- if (val == NULL)
- return NULL;
-
- db_add_session(ctx, user, realm, session_id, NULL, redirect_uri,
- USER_REMEDIATION, NULL);
-
- snprintf(uri, sizeof(uri), "%s%s", val, session_id);
- os_free(val);
- return browser_remediation(ctx, session_id, redirect_uri, uri);
-}
-
-
-static xml_node_t * free_remediation(struct hs20_svc *ctx,
- const char *user, const char *realm,
- const char *session_id,
- const char *redirect_uri)
-{
- char uri[300], *val;
-
- hs20_eventlog(ctx, user, realm, session_id,
- "requires free/public account remediation", NULL);
- val = db_get_osu_config_val(ctx, realm, "free_remediation_url");
- if (val == NULL)
- return NULL;
-
- db_add_session(ctx, user, realm, session_id, NULL, redirect_uri,
- FREE_REMEDIATION, NULL);
-
- snprintf(uri, sizeof(uri), "%s%s", val, session_id);
- os_free(val);
- return browser_remediation(ctx, session_id, redirect_uri, uri);
-}
-
-
-static xml_node_t * no_sub_rem(struct hs20_svc *ctx,
- const char *user, const char *realm,
- const char *session_id)
-{
- const char *status;
-
- hs20_eventlog(ctx, user, realm, session_id,
- "no subscription mediation available", NULL);
-
- status = "No update available at this time";
- return build_post_dev_data_response(ctx, NULL, session_id, status,
- NULL);
-}
-
-
-static xml_node_t * hs20_subscription_remediation(struct hs20_svc *ctx,
- const char *user,
- const char *realm,
- const char *session_id,
- int dmacc,
- const char *redirect_uri)
-{
- char *type, *identity;
- xml_node_t *ret;
- char *free_account;
-
- identity = db_get_val(ctx, user, realm, "identity", dmacc);
- if (identity == NULL || strlen(identity) == 0) {
- hs20_eventlog(ctx, user, realm, session_id,
- "user not found in database for remediation",
- NULL);
- os_free(identity);
- return build_post_dev_data_response(ctx, NULL, session_id,
- "Error occurred",
- "Not found");
- }
- os_free(identity);
-
- free_account = db_get_osu_config_val(ctx, realm, "free_account");
- if (free_account && strcmp(free_account, user) == 0) {
- free(free_account);
- return no_sub_rem(ctx, user, realm, session_id);
- }
- free(free_account);
-
- type = db_get_val(ctx, user, realm, "remediation", dmacc);
- if (type && strcmp(type, "free") != 0) {
- char *val;
- int shared = 0;
- val = db_get_val(ctx, user, realm, "shared", dmacc);
- if (val)
- shared = atoi(val);
- free(val);
- if (shared) {
- free(type);
- return no_sub_rem(ctx, user, realm, session_id);
- }
- }
- if (type && strcmp(type, "user") == 0)
- ret = user_remediation(ctx, user, realm, session_id,
- redirect_uri);
- else if (type && strcmp(type, "free") == 0)
- ret = free_remediation(ctx, user, realm, session_id,
- redirect_uri);
- else if (type && strcmp(type, "policy") == 0)
- ret = policy_remediation(ctx, user, realm, session_id, dmacc);
- else if (type && strcmp(type, "machine") == 0)
- ret = machine_remediation(ctx, user, realm, session_id, dmacc);
- else if (type && strcmp(type, "reenroll") == 0)
- ret = cert_reenroll(ctx, user, realm, session_id);
- else
- ret = no_sub_rem(ctx, user, realm, session_id);
- free(type);
-
- return ret;
-}
-
-
-static xml_node_t * read_policy_file(struct hs20_svc *ctx,
- const char *policy_id)
-{
- char fname[200];
-
- snprintf(fname, sizeof(fname), "%s/spp/policy/%s.xml",
- ctx->root_dir, policy_id);
- debug_print(ctx, 1, "Use policy file %s", fname);
-
- return node_from_file(ctx->xml, fname);
-}
-
-
-static void update_policy_update_uri(struct hs20_svc *ctx, const char *realm,
- xml_node_t *policy)
-{
- xml_node_t *node;
- char *url;
-
- node = get_node_uri(ctx->xml, policy, "Policy/PolicyUpdate/URI");
- if (!node)
- return;
-
- url = db_get_osu_config_val(ctx, realm, "policy_url");
- if (!url)
- return;
- xml_node_set_text(ctx->xml, node, url);
- free(url);
-}
-
-
-static xml_node_t * build_policy(struct hs20_svc *ctx, const char *user,
- const char *realm, int use_dmacc)
-{
- char *policy_id;
- xml_node_t *policy, *node;
-
- policy_id = db_get_val(ctx, user, realm, "policy", use_dmacc);
- if (policy_id == NULL || strlen(policy_id) == 0) {
- free(policy_id);
- policy_id = strdup("default");
- if (policy_id == NULL)
- return NULL;
- }
- policy = read_policy_file(ctx, policy_id);
- free(policy_id);
- if (policy == NULL)
- return NULL;
-
- update_policy_update_uri(ctx, realm, policy);
-
- node = get_node_uri(ctx->xml, policy, "Policy/PolicyUpdate");
- if (node && use_dmacc) {
- char *pw;
- pw = db_get_val(ctx, user, realm, "osu_password", use_dmacc);
- if (pw == NULL ||
- build_username_password(ctx, node, user, pw) == NULL) {
- debug_print(ctx, 1, "Failed to add Policy/PolicyUpdate/"
- "UsernamePassword");
- free(pw);
- xml_node_free(ctx->xml, policy);
- return NULL;
- }
- free(pw);
- }
-
- return policy;
-}
-
-
-static xml_node_t * hs20_policy_update(struct hs20_svc *ctx,
- const char *user, const char *realm,
- const char *session_id, int dmacc)
-{
- xml_namespace_t *ns;
- xml_node_t *spp_node;
- xml_node_t *policy;
- char buf[400];
- const char *status;
- char *identity;
-
- identity = db_get_val(ctx, user, realm, "identity", dmacc);
- if (identity == NULL || strlen(identity) == 0) {
- hs20_eventlog(ctx, user, realm, session_id,
- "user not found in database for policy update",
- NULL);
- os_free(identity);
- return build_post_dev_data_response(ctx, NULL, session_id,
- "Error occurred",
- "Not found");
- }
- os_free(identity);
-
- policy = build_policy(ctx, user, realm, dmacc);
- if (!policy) {
- return build_post_dev_data_response(
- ctx, NULL, session_id,
- "No update available at this time", NULL);
- }
-
- db_add_session(ctx, user, realm, session_id, NULL, NULL, POLICY_UPDATE,
- NULL);
-
- status = "Update complete, request sppUpdateResponse";
- spp_node = build_post_dev_data_response(ctx, &ns, session_id, status,
- NULL);
- if (spp_node == NULL)
- return NULL;
-
- snprintf(buf, sizeof(buf),
- "./Wi-Fi/%s/PerProviderSubscription/Cred01/Policy",
- realm);
-
- if (add_update_node(ctx, spp_node, ns, buf, policy) < 0) {
- xml_node_free(ctx->xml, spp_node);
- xml_node_free(ctx->xml, policy);
- return NULL;
- }
-
- hs20_eventlog_node(ctx, user, realm, session_id, "policy update",
- policy);
- xml_node_free(ctx->xml, policy);
-
- return spp_node;
-}
-
-
-static xml_node_t * spp_get_mo(struct hs20_svc *ctx, xml_node_t *node,
- const char *urn, int *valid, char **ret_err)
-{
- xml_node_t *child, *tnds, *mo;
- const char *name;
- char *mo_urn;
- char *str;
- char fname[200];
-
- *valid = -1;
- if (ret_err)
- *ret_err = NULL;
-
- xml_node_for_each_child(ctx->xml, child, node) {
- xml_node_for_each_check(ctx->xml, child);
- name = xml_node_get_localname(ctx->xml, child);
- if (strcmp(name, "moContainer") != 0)
- continue;
- mo_urn = xml_node_get_attr_value_ns(ctx->xml, child, SPP_NS_URI,
- "moURN");
- if (strcasecmp(urn, mo_urn) == 0) {
- xml_node_get_attr_value_free(ctx->xml, mo_urn);
- break;
- }
- xml_node_get_attr_value_free(ctx->xml, mo_urn);
- }
-
- if (child == NULL)
- return NULL;
-
- debug_print(ctx, 1, "moContainer text for %s", urn);
- debug_dump_node(ctx, "moContainer", child);
-
- str = xml_node_get_text(ctx->xml, child);
- debug_print(ctx, 1, "moContainer payload: '%s'", str);
- tnds = xml_node_from_buf(ctx->xml, str);
- xml_node_get_text_free(ctx->xml, str);
- if (tnds == NULL) {
- debug_print(ctx, 1, "could not parse moContainer text");
- return NULL;
- }
-
- snprintf(fname, sizeof(fname), "%s/spp/dm_ddf-v1_2.dtd", ctx->root_dir);
- if (xml_validate_dtd(ctx->xml, tnds, fname, ret_err) == 0)
- *valid = 1;
- else if (ret_err && *ret_err &&
- os_strcmp(*ret_err, "No declaration for attribute xmlns of element MgmtTree\n") == 0) {
- free(*ret_err);
- debug_print(ctx, 1, "Ignore OMA-DM DDF DTD validation error for MgmtTree namespace declaration with xmlns attribute");
- *ret_err = NULL;
- *valid = 1;
- } else
- *valid = 0;
-
- mo = tnds_to_mo(ctx->xml, tnds);
- xml_node_free(ctx->xml, tnds);
- if (mo == NULL) {
- debug_print(ctx, 1, "invalid moContainer for %s", urn);
- }
-
- return mo;
-}
-
-
-static xml_node_t * spp_exec_upload_mo(struct hs20_svc *ctx,
- const char *session_id, const char *urn)
-{
- xml_namespace_t *ns;
- xml_node_t *spp_node, *node, *exec_node;
-
- spp_node = build_post_dev_data_response(ctx, &ns, session_id, "OK",
- NULL);
- if (spp_node == NULL)
- return NULL;
-
- exec_node = xml_node_create(ctx->xml, spp_node, ns, "exec");
-
- node = xml_node_create(ctx->xml, exec_node, ns, "uploadMO");
- xml_node_add_attr(ctx->xml, node, ns, "moURN", urn);
-
- return spp_node;
-}
-
-
-static xml_node_t * hs20_subscription_registration(struct hs20_svc *ctx,
- const char *realm,
- const char *session_id,
- const char *redirect_uri,
- const u8 *mac_addr)
-{
- xml_namespace_t *ns;
- xml_node_t *spp_node, *exec_node;
- char uri[300], *val;
-
- if (db_add_session(ctx, NULL, realm, session_id, NULL, redirect_uri,
- SUBSCRIPTION_REGISTRATION, mac_addr) < 0)
- return NULL;
- val = db_get_osu_config_val(ctx, realm, "signup_url");
- if (!val) {
- hs20_eventlog(ctx, NULL, realm, session_id,
- "signup_url not configured in osu_config", NULL);
- return NULL;
- }
-
- spp_node = build_post_dev_data_response(ctx, &ns, session_id, "OK",
- NULL);
- if (spp_node == NULL)
- return NULL;
-
- exec_node = xml_node_create(ctx->xml, spp_node, ns, "exec");
-
- snprintf(uri, sizeof(uri), "%s%s", val, session_id);
- os_free(val);
- xml_node_create_text(ctx->xml, exec_node, ns, "launchBrowserToURI",
- uri);
- return spp_node;
-}
-
-
-static xml_node_t * hs20_user_input_remediation(struct hs20_svc *ctx,
- const char *user,
- const char *realm, int dmacc,
- const char *session_id)
-{
- return build_sub_rem_resp(ctx, user, realm, session_id, 0, dmacc);
-}
-
-
-static char * db_get_osu_config_val(struct hs20_svc *ctx, const char *realm,
- const char *field)
-{
- char *cmd;
- struct get_db_field_data data;
-
- cmd = sqlite3_mprintf("SELECT value FROM osu_config WHERE realm=%Q AND "
- "field=%Q", realm, field);
- if (cmd == NULL)
- return NULL;
- debug_print(ctx, 1, "DB: %s", cmd);
- memset(&data, 0, sizeof(data));
- data.field = "value";
- if (sqlite3_exec(ctx->db, cmd, get_db_field, &data, NULL) != SQLITE_OK)
- {
- debug_print(ctx, 1, "DB: Could not find osu_config %s: %s",
- realm, sqlite3_errmsg(ctx->db));
- sqlite3_free(cmd);
- return NULL;
- }
- sqlite3_free(cmd);
-
- debug_print(ctx, 1, "DB: return '%s'", data.value);
- return data.value;
-}
-
-
-static xml_node_t * build_pps(struct hs20_svc *ctx,
- const char *user, const char *realm,
- const char *pw, const char *cert,
- int machine_managed, const char *test,
- const char *imsi, const char *dmacc_username,
- const char *dmacc_password,
- xml_node_t *policy_node)
-{
- xml_node_t *pps, *c, *trust, *aaa, *aaa1, *upd, *homesp, *p;
- xml_node_t *cred, *eap, *userpw;
-
- pps = xml_node_create_root(ctx->xml, NULL, NULL, NULL,
- "PerProviderSubscription");
- if (!pps) {
- xml_node_free(ctx->xml, policy_node);
- return NULL;
- }
-
- add_text_node(ctx, pps, "UpdateIdentifier", "1");
-
- c = xml_node_create(ctx->xml, pps, NULL, "Cred01");
-
- add_text_node(ctx, c, "CredentialPriority", "1");
-
- if (imsi)
- goto skip_aaa_trust_root;
- aaa = xml_node_create(ctx->xml, c, NULL, "AAAServerTrustRoot");
- aaa1 = xml_node_create(ctx->xml, aaa, NULL, "AAA1");
- add_text_node_conf(ctx, realm, aaa1, "CertURL",
- "aaa_trust_root_cert_url");
- if (test && os_strcmp(test, "corrupt_aaa_hash") == 0) {
- debug_print(ctx, 1,
- "TEST: Corrupt PPS/Cred*/AAAServerTrustRoot/Root*/CertSHA256FingerPrint");
- add_text_node_conf_corrupt(ctx, realm, aaa1,
- "CertSHA256Fingerprint",
- "aaa_trust_root_cert_fingerprint");
- } else {
- add_text_node_conf(ctx, realm, aaa1, "CertSHA256Fingerprint",
- "aaa_trust_root_cert_fingerprint");
- }
-
- if (test && os_strcmp(test, "corrupt_polupd_hash") == 0) {
- debug_print(ctx, 1,
- "TEST: Corrupt PPS/Cred*/Policy/PolicyUpdate/Trustroot/CertSHA256FingerPrint");
- p = xml_node_create(ctx->xml, c, NULL, "Policy");
- upd = xml_node_create(ctx->xml, p, NULL, "PolicyUpdate");
- add_text_node(ctx, upd, "UpdateInterval", "30");
- add_text_node(ctx, upd, "UpdateMethod", "SPP-ClientInitiated");
- add_text_node(ctx, upd, "Restriction", "Unrestricted");
- add_text_node_conf(ctx, realm, upd, "URI", "policy_url");
- trust = xml_node_create(ctx->xml, upd, NULL, "TrustRoot");
- add_text_node_conf(ctx, realm, trust, "CertURL",
- "policy_trust_root_cert_url");
- add_text_node_conf_corrupt(ctx, realm, trust,
- "CertSHA256Fingerprint",
- "policy_trust_root_cert_fingerprint");
- }
-skip_aaa_trust_root:
-
- upd = xml_node_create(ctx->xml, c, NULL, "SubscriptionUpdate");
- add_text_node(ctx, upd, "UpdateInterval", "4294967295");
- add_text_node(ctx, upd, "UpdateMethod", "SPP-ClientInitiated");
- add_text_node(ctx, upd, "Restriction", "HomeSP");
- add_text_node_conf(ctx, realm, upd, "URI", "spp_http_auth_url");
- trust = xml_node_create(ctx->xml, upd, NULL, "TrustRoot");
- add_text_node_conf(ctx, realm, trust, "CertURL", "trust_root_cert_url");
- if (test && os_strcmp(test, "corrupt_subrem_hash") == 0) {
- debug_print(ctx, 1,
- "TEST: Corrupt PPS/Cred*/SubscriptionUpdate/Trustroot/CertSHA256FingerPrint");
- add_text_node_conf_corrupt(ctx, realm, trust,
- "CertSHA256Fingerprint",
- "trust_root_cert_fingerprint");
- } else {
- add_text_node_conf(ctx, realm, trust, "CertSHA256Fingerprint",
- "trust_root_cert_fingerprint");
- }
-
- if (dmacc_username &&
- !build_username_password(ctx, upd, dmacc_username,
- dmacc_password)) {
- xml_node_free(ctx->xml, pps);
- xml_node_free(ctx->xml, policy_node);
- return NULL;
- }
-
- if (policy_node)
- xml_node_add_child(ctx->xml, c, policy_node);
-
- homesp = xml_node_create(ctx->xml, c, NULL, "HomeSP");
- add_text_node_conf(ctx, realm, homesp, "FriendlyName", "friendly_name");
- add_text_node_conf(ctx, realm, homesp, "FQDN", "fqdn");
-
- xml_node_create(ctx->xml, c, NULL, "SubscriptionParameters");
-
- cred = xml_node_create(ctx->xml, c, NULL, "Credential");
- add_creation_date(ctx, cred);
- if (imsi) {
- xml_node_t *sim;
- const char *type = "18"; /* default to EAP-SIM */
-
- sim = xml_node_create(ctx->xml, cred, NULL, "SIM");
- add_text_node(ctx, sim, "IMSI", imsi);
- if (ctx->eap_method && os_strcmp(ctx->eap_method, "AKA") == 0)
- type = "23";
- else if (ctx->eap_method &&
- os_strcmp(ctx->eap_method, "AKA'") == 0)
- type = "50";
- add_text_node(ctx, sim, "EAPType", type);
- } else if (cert) {
- xml_node_t *dc;
- dc = xml_node_create(ctx->xml, cred, NULL,
- "DigitalCertificate");
- add_text_node(ctx, dc, "CertificateType", "x509v3");
- add_text_node(ctx, dc, "CertSHA256Fingerprint", cert);
- } else {
- userpw = build_username_password(ctx, cred, user, pw);
- add_text_node(ctx, userpw, "MachineManaged",
- machine_managed ? "TRUE" : "FALSE");
- eap = xml_node_create(ctx->xml, userpw, NULL, "EAPMethod");
- add_text_node(ctx, eap, "EAPType", "21");
- add_text_node(ctx, eap, "InnerMethod", "MS-CHAP-V2");
- }
- add_text_node(ctx, cred, "Realm", realm);
-
- return pps;
-}
-
-
-static xml_node_t * spp_exec_get_certificate(struct hs20_svc *ctx,
- const char *session_id,
- const char *user,
- const char *realm,
- int add_est_user)
-{
- xml_namespace_t *ns;
- xml_node_t *spp_node, *enroll, *exec_node;
- char *val;
- char password[11];
- char *b64;
-
- if (add_est_user && new_password(password, sizeof(password)) < 0)
- return NULL;
-
- spp_node = build_post_dev_data_response(ctx, &ns, session_id, "OK",
- NULL);
- if (spp_node == NULL)
- return NULL;
-
- exec_node = xml_node_create(ctx->xml, spp_node, ns, "exec");
-
- enroll = xml_node_create(ctx->xml, exec_node, ns, "getCertificate");
- xml_node_add_attr(ctx->xml, enroll, NULL, "enrollmentProtocol", "EST");
-
- val = db_get_osu_config_val(ctx, realm, "est_url");
- xml_node_create_text(ctx->xml, enroll, ns, "enrollmentServerURI",
- val ? val : "");
- os_free(val);
-
- if (!add_est_user)
- return spp_node;
-
- xml_node_create_text(ctx->xml, enroll, ns, "estUserID", user);
-
- b64 = base64_encode(password, strlen(password), NULL);
- if (b64 == NULL) {
- xml_node_free(ctx->xml, spp_node);
- return NULL;
- }
- xml_node_create_text(ctx->xml, enroll, ns, "estPassword", b64);
- free(b64);
-
- db_update_session_password(ctx, user, realm, session_id, password);
-
- return spp_node;
-}
-
-
-static xml_node_t * hs20_user_input_registration(struct hs20_svc *ctx,
- const char *session_id,
- int enrollment_done)
-{
- xml_namespace_t *ns;
- xml_node_t *spp_node, *node = NULL;
- xml_node_t *pps, *tnds;
- char buf[400];
- char *str;
- char *user, *realm, *pw, *type, *mm, *test;
- const char *status;
- int cert = 0;
- int machine_managed = 0;
- char *fingerprint;
-
- user = db_get_session_val(ctx, NULL, NULL, session_id, "user");
- realm = db_get_session_val(ctx, NULL, NULL, session_id, "realm");
- pw = db_get_session_val(ctx, NULL, NULL, session_id, "password");
-
- if (!user || !realm || !pw) {
- debug_print(ctx, 1, "Could not find session info from DB for "
- "the new subscription");
- free(user);
- free(realm);
- free(pw);
- return NULL;
- }
-
- mm = db_get_session_val(ctx, NULL, NULL, session_id, "machine_managed");
- if (mm && atoi(mm))
- machine_managed = 1;
- free(mm);
-
- type = db_get_session_val(ctx, NULL, NULL, session_id, "type");
- if (type && strcmp(type, "cert") == 0)
- cert = 1;
- free(type);
-
- if (cert && !enrollment_done) {
- xml_node_t *ret;
- hs20_eventlog(ctx, user, realm, session_id,
- "request client certificate enrollment", NULL);
- ret = spp_exec_get_certificate(ctx, session_id, user, realm, 1);
- free(user);
- free(realm);
- free(pw);
- return ret;
- }
-
- if (!cert && strlen(pw) == 0) {
- machine_managed = 1;
- free(pw);
- pw = malloc(11);
- if (pw == NULL || new_password(pw, 11) < 0) {
- free(user);
- free(realm);
- free(pw);
- return NULL;
- }
- }
-
- status = "Provisioning complete, request sppUpdateResponse";
- spp_node = build_post_dev_data_response(ctx, &ns, session_id, status,
- NULL);
- if (spp_node == NULL)
- return NULL;
-
- fingerprint = db_get_session_val(ctx, NULL, NULL, session_id, "cert");
- test = db_get_session_val(ctx, NULL, NULL, session_id, "test");
- if (test)
- debug_print(ctx, 1, "TEST: Requested special behavior: %s",
- test);
- pps = build_pps(ctx, user, realm, pw,
- fingerprint ? fingerprint : NULL, machine_managed,
- test, NULL, NULL, NULL, NULL);
- free(fingerprint);
- free(test);
- if (!pps) {
- xml_node_free(ctx->xml, spp_node);
- free(user);
- free(realm);
- free(pw);
- return NULL;
- }
-
- debug_print(ctx, 1, "Request DB subscription registration on success "
- "notification");
- if (machine_managed) {
- db_update_session_password(ctx, user, realm, session_id, pw);
- db_update_session_machine_managed(ctx, user, realm, session_id,
- machine_managed);
- }
- db_add_session_pps(ctx, user, realm, session_id, pps);
-
- hs20_eventlog_node(ctx, user, realm, session_id,
- "new subscription", pps);
- free(user);
- free(pw);
-
- tnds = mo_to_tnds(ctx->xml, pps, 0, URN_HS20_PPS, NULL);
- xml_node_free(ctx->xml, pps);
- if (!tnds) {
- xml_node_free(ctx->xml, spp_node);
- free(realm);
- return NULL;
- }
-
- str = xml_node_to_str(ctx->xml, tnds);
- xml_node_free(ctx->xml, tnds);
- if (str == NULL) {
- xml_node_free(ctx->xml, spp_node);
- free(realm);
- return NULL;
- }
-
- node = xml_node_create_text(ctx->xml, spp_node, ns, "addMO", str);
- free(str);
- snprintf(buf, sizeof(buf), "./Wi-Fi/%s/PerProviderSubscription", realm);
- free(realm);
- xml_node_add_attr(ctx->xml, node, ns, "managementTreeURI", buf);
- xml_node_add_attr(ctx->xml, node, ns, "moURN", URN_HS20_PPS);
-
- return spp_node;
-}
-
-
-static xml_node_t * hs20_user_input_free_remediation(struct hs20_svc *ctx,
- const char *user,
- const char *realm,
- const char *session_id)
-{
- xml_namespace_t *ns;
- xml_node_t *spp_node;
- xml_node_t *cred;
- char buf[400];
- char *status;
- char *free_account, *pw;
-
- free_account = db_get_osu_config_val(ctx, realm, "free_account");
- if (free_account == NULL)
- return NULL;
- pw = db_get_val(ctx, free_account, realm, "password", 0);
- if (pw == NULL) {
- free(free_account);
- return NULL;
- }
-
- cred = build_credential_pw(ctx, free_account, realm, pw, 1);
- free(free_account);
- free(pw);
- if (!cred) {
- xml_node_free(ctx->xml, cred);
- return NULL;
- }
-
- status = "Remediation complete, request sppUpdateResponse";
- spp_node = build_post_dev_data_response(ctx, &ns, session_id, status,
- NULL);
- if (spp_node == NULL)
- return NULL;
-
- snprintf(buf, sizeof(buf),
- "./Wi-Fi/%s/PerProviderSubscription/Cred01/Credential",
- realm);
-
- if (add_update_node(ctx, spp_node, ns, buf, cred) < 0) {
- xml_node_free(ctx->xml, spp_node);
- return NULL;
- }
-
- hs20_eventlog_node(ctx, user, realm, session_id,
- "free/public remediation", cred);
- xml_node_free(ctx->xml, cred);
-
- return spp_node;
-}
-
-
-static xml_node_t * hs20_user_input_complete(struct hs20_svc *ctx,
- const char *user,
- const char *realm, int dmacc,
- const char *session_id)
-{
- char *val;
- enum hs20_session_operation oper;
-
- val = db_get_session_val(ctx, user, realm, session_id, "operation");
- if (val == NULL) {
- debug_print(ctx, 1, "No session %s found to continue",
- session_id);
- return NULL;
- }
- oper = atoi(val);
- free(val);
-
- if (oper == USER_REMEDIATION) {
- return hs20_user_input_remediation(ctx, user, realm, dmacc,
- session_id);
- }
-
- if (oper == FREE_REMEDIATION) {
- return hs20_user_input_free_remediation(ctx, user, realm,
- session_id);
- }
-
- if (oper == SUBSCRIPTION_REGISTRATION) {
- return hs20_user_input_registration(ctx, session_id, 0);
- }
-
- debug_print(ctx, 1, "User session %s not in state for user input "
- "completion", session_id);
- return NULL;
-}
-
-
-static xml_node_t * hs20_cert_reenroll_complete(struct hs20_svc *ctx,
- const char *session_id)
-{
- char *user, *realm, *cert;
- char *status;
- xml_namespace_t *ns;
- xml_node_t *spp_node, *cred;
- char buf[400];
-
- user = db_get_session_val(ctx, NULL, NULL, session_id, "user");
- realm = db_get_session_val(ctx, NULL, NULL, session_id, "realm");
- cert = db_get_session_val(ctx, NULL, NULL, session_id, "cert");
- if (!user || !realm || !cert) {
- debug_print(ctx, 1,
- "Could not find session info from DB for certificate reenrollment");
- free(user);
- free(realm);
- free(cert);
- return NULL;
- }
-
- cred = build_credential_cert(ctx, user, realm, cert);
- if (!cred) {
- debug_print(ctx, 1, "Could not build credential");
- free(user);
- free(realm);
- free(cert);
- return NULL;
- }
-
- status = "Remediation complete, request sppUpdateResponse";
- spp_node = build_post_dev_data_response(ctx, &ns, session_id, status,
- NULL);
- if (spp_node == NULL) {
- debug_print(ctx, 1, "Could not build sppPostDevDataResponse");
- free(user);
- free(realm);
- free(cert);
- xml_node_free(ctx->xml, cred);
- return NULL;
- }
-
- snprintf(buf, sizeof(buf),
- "./Wi-Fi/%s/PerProviderSubscription/Cred01/Credential",
- realm);
-
- if (add_update_node(ctx, spp_node, ns, buf, cred) < 0) {
- debug_print(ctx, 1, "Could not add update node");
- xml_node_free(ctx->xml, spp_node);
- free(user);
- free(realm);
- free(cert);
- return NULL;
- }
-
- hs20_eventlog_node(ctx, user, realm, session_id,
- "certificate reenrollment", cred);
- xml_node_free(ctx->xml, cred);
-
- free(user);
- free(realm);
- free(cert);
- return spp_node;
-}
-
-
-static xml_node_t * hs20_cert_enroll_completed(struct hs20_svc *ctx,
- const char *user,
- const char *realm, int dmacc,
- const char *session_id)
-{
- char *val;
- enum hs20_session_operation oper;
-
- val = db_get_session_val(ctx, NULL, NULL, session_id, "operation");
- if (val == NULL) {
- debug_print(ctx, 1, "No session %s found to continue",
- session_id);
- return NULL;
- }
- oper = atoi(val);
- free(val);
-
- if (oper == SUBSCRIPTION_REGISTRATION)
- return hs20_user_input_registration(ctx, session_id, 1);
- if (oper == CERT_REENROLL)
- return hs20_cert_reenroll_complete(ctx, session_id);
-
- debug_print(ctx, 1, "User session %s not in state for certificate "
- "enrollment completion", session_id);
- return NULL;
-}
-
-
-static xml_node_t * hs20_cert_enroll_failed(struct hs20_svc *ctx,
- const char *user,
- const char *realm, int dmacc,
- const char *session_id)
-{
- char *val;
- enum hs20_session_operation oper;
- xml_node_t *spp_node, *node;
- char *status;
- xml_namespace_t *ns;
-
- val = db_get_session_val(ctx, user, realm, session_id, "operation");
- if (val == NULL) {
- debug_print(ctx, 1, "No session %s found to continue",
- session_id);
- return NULL;
- }
- oper = atoi(val);
- free(val);
-
- if (oper != SUBSCRIPTION_REGISTRATION) {
- debug_print(ctx, 1, "User session %s not in state for "
- "enrollment failure", session_id);
- return NULL;
- }
-
- status = "Error occurred";
- spp_node = build_post_dev_data_response(ctx, &ns, session_id, status,
- NULL);
- if (spp_node == NULL)
- return NULL;
- node = xml_node_create(ctx->xml, spp_node, ns, "sppError");
- xml_node_add_attr(ctx->xml, node, NULL, "errorCode",
- "Credentials cannot be provisioned at this time");
- db_remove_session(ctx, user, realm, session_id);
-
- return spp_node;
-}
-
-
-static xml_node_t * hs20_sim_provisioning(struct hs20_svc *ctx,
- const char *user,
- const char *realm, int dmacc,
- const char *session_id)
-{
- xml_namespace_t *ns;
- xml_node_t *spp_node, *node = NULL;
- xml_node_t *pps, *tnds;
- char buf[400];
- char *str;
- const char *status;
- char dmacc_username[32];
- char dmacc_password[32];
- char *policy;
- xml_node_t *policy_node = NULL;
-
- if (!ctx->imsi) {
- debug_print(ctx, 1, "IMSI not available for SIM provisioning");
- return NULL;
- }
-
- if (new_password(dmacc_username, sizeof(dmacc_username)) < 0 ||
- new_password(dmacc_password, sizeof(dmacc_password)) < 0) {
- debug_print(ctx, 1,
- "Failed to generate DMAcc username/password");
- return NULL;
- }
-
- status = "Provisioning complete, request sppUpdateResponse";
- spp_node = build_post_dev_data_response(ctx, &ns, session_id, status,
- NULL);
- if (!spp_node)
- return NULL;
-
- policy = db_get_osu_config_val(ctx, realm, "sim_policy");
- if (policy) {
- policy_node = read_policy_file(ctx, policy);
- os_free(policy);
- if (!policy_node) {
- xml_node_free(ctx->xml, spp_node);
- return NULL;
- }
- update_policy_update_uri(ctx, realm, policy_node);
- node = get_node_uri(ctx->xml, policy_node,
- "Policy/PolicyUpdate");
- if (node)
- build_username_password(ctx, node, dmacc_username,
- dmacc_password);
- }
-
- pps = build_pps(ctx, NULL, realm, NULL, NULL, 0, NULL, ctx->imsi,
- dmacc_username, dmacc_password, policy_node);
- if (!pps) {
- xml_node_free(ctx->xml, spp_node);
- return NULL;
- }
-
- debug_print(ctx, 1,
- "Request DB subscription registration on success notification");
- if (!user || !user[0])
- user = ctx->imsi;
- db_add_session(ctx, user, realm, session_id, NULL, NULL,
- SUBSCRIPTION_REGISTRATION, NULL);
- db_add_session_dmacc(ctx, session_id, dmacc_username, dmacc_password);
- if (ctx->eap_method)
- db_add_session_eap_method(ctx, session_id, ctx->eap_method);
- if (ctx->id_hash)
- db_add_session_id_hash(ctx, session_id, ctx->id_hash);
- db_add_session_pps(ctx, user, realm, session_id, pps);
-
- hs20_eventlog_node(ctx, user, realm, session_id,
- "new subscription", pps);
-
- tnds = mo_to_tnds(ctx->xml, pps, 0, URN_HS20_PPS, NULL);
- xml_node_free(ctx->xml, pps);
- if (!tnds) {
- xml_node_free(ctx->xml, spp_node);
- return NULL;
- }
-
- str = xml_node_to_str(ctx->xml, tnds);
- xml_node_free(ctx->xml, tnds);
- if (!str) {
- xml_node_free(ctx->xml, spp_node);
- return NULL;
- }
-
- node = xml_node_create_text(ctx->xml, spp_node, ns, "addMO", str);
- free(str);
- snprintf(buf, sizeof(buf), "./Wi-Fi/%s/PerProviderSubscription", realm);
- xml_node_add_attr(ctx->xml, node, ns, "managementTreeURI", buf);
- xml_node_add_attr(ctx->xml, node, ns, "moURN", URN_HS20_PPS);
-
- return spp_node;
-}
-
-
-static xml_node_t * hs20_spp_post_dev_data(struct hs20_svc *ctx,
- xml_node_t *node,
- const char *user,
- const char *realm,
- const char *session_id,
- int dmacc)
-{
- const char *req_reason;
- char *redirect_uri = NULL;
- char *req_reason_buf = NULL;
- char str[200];
- xml_node_t *ret = NULL, *devinfo = NULL, *devdetail = NULL;
- xml_node_t *mo, *macaddr;
- char *version;
- int valid;
- char *supp, *pos;
- char *err;
- u8 wifi_mac_addr[ETH_ALEN];
-
- version = xml_node_get_attr_value_ns(ctx->xml, node, SPP_NS_URI,
- "sppVersion");
- if (version == NULL || strstr(version, "1.0") == NULL) {
- ret = build_post_dev_data_response(
- ctx, NULL, session_id, "Error occurred",
- "SPP version not supported");
- hs20_eventlog_node(ctx, user, realm, session_id,
- "Unsupported sppVersion", ret);
- xml_node_get_attr_value_free(ctx->xml, version);
- return ret;
- }
- xml_node_get_attr_value_free(ctx->xml, version);
-
- mo = get_node(ctx->xml, node, "supportedMOList");
- if (mo == NULL) {
- ret = build_post_dev_data_response(
- ctx, NULL, session_id, "Error occurred",
- "Other");
- hs20_eventlog_node(ctx, user, realm, session_id,
- "No supportedMOList element", ret);
- return ret;
- }
- supp = xml_node_get_text(ctx->xml, mo);
- for (pos = supp; pos && *pos; pos++)
- *pos = tolower(*pos);
- if (supp == NULL ||
- strstr(supp, URN_OMA_DM_DEVINFO) == NULL ||
- strstr(supp, URN_OMA_DM_DEVDETAIL) == NULL ||
- strstr(supp, URN_HS20_PPS) == NULL) {
- xml_node_get_text_free(ctx->xml, supp);
- ret = build_post_dev_data_response(
- ctx, NULL, session_id, "Error occurred",
- "One or more mandatory MOs not supported");
- hs20_eventlog_node(ctx, user, realm, session_id,
- "Unsupported MOs", ret);
- return ret;
- }
- xml_node_get_text_free(ctx->xml, supp);
-
- req_reason_buf = xml_node_get_attr_value(ctx->xml, node,
- "requestReason");
- if (req_reason_buf == NULL) {
- debug_print(ctx, 1, "No requestReason attribute");
- return NULL;
- }
- req_reason = req_reason_buf;
-
- redirect_uri = xml_node_get_attr_value(ctx->xml, node, "redirectURI");
-
- debug_print(ctx, 1, "requestReason: %s sessionID: %s redirectURI: %s",
- req_reason, session_id, redirect_uri);
- snprintf(str, sizeof(str), "sppPostDevData: requestReason=%s",
- req_reason);
- hs20_eventlog(ctx, user, realm, session_id, str, NULL);
-
- devinfo = spp_get_mo(ctx, node, URN_OMA_DM_DEVINFO, &valid, &err);
- if (devinfo == NULL) {
- ret = build_post_dev_data_response(ctx, NULL, session_id,
- "Error occurred", "Other");
- hs20_eventlog_node(ctx, user, realm, session_id,
- "No DevInfo moContainer in sppPostDevData",
- ret);
- os_free(err);
- goto out;
- }
-
- hs20_eventlog_node(ctx, user, realm, session_id,
- "Received DevInfo MO", devinfo);
- if (valid == 0) {
- hs20_eventlog(ctx, user, realm, session_id,
- "OMA-DM DDF DTD validation errors in DevInfo MO",
- err);
- ret = build_post_dev_data_response(ctx, NULL, session_id,
- "Error occurred", "Other");
- os_free(err);
- goto out;
- }
- os_free(err);
- if (user)
- db_update_mo(ctx, user, realm, "devinfo", devinfo);
-
- devdetail = spp_get_mo(ctx, node, URN_OMA_DM_DEVDETAIL, &valid, &err);
- if (devdetail == NULL) {
- ret = build_post_dev_data_response(ctx, NULL, session_id,
- "Error occurred", "Other");
- hs20_eventlog_node(ctx, user, realm, session_id,
- "No DevDetail moContainer in sppPostDevData",
- ret);
- os_free(err);
- goto out;
- }
-
- hs20_eventlog_node(ctx, user, realm, session_id,
- "Received DevDetail MO", devdetail);
- if (valid == 0) {
- hs20_eventlog(ctx, user, realm, session_id,
- "OMA-DM DDF DTD validation errors "
- "in DevDetail MO", err);
- ret = build_post_dev_data_response(ctx, NULL, session_id,
- "Error occurred", "Other");
- os_free(err);
- goto out;
- }
- os_free(err);
-
- os_memset(wifi_mac_addr, 0, ETH_ALEN);
- macaddr = get_node(ctx->xml, devdetail,
- "Ext/org.wi-fi/Wi-Fi/Wi-FiMACAddress");
- if (macaddr) {
- char *addr, buf[50];
-
- addr = xml_node_get_text(ctx->xml, macaddr);
- if (addr && hwaddr_compact_aton(addr, wifi_mac_addr) == 0) {
- snprintf(buf, sizeof(buf), "DevDetail MAC address: "
- MACSTR, MAC2STR(wifi_mac_addr));
- hs20_eventlog(ctx, user, realm, session_id, buf, NULL);
- xml_node_get_text_free(ctx->xml, addr);
- } else {
- hs20_eventlog(ctx, user, realm, session_id,
- "Could not extract MAC address from DevDetail",
- NULL);
- }
- } else {
- hs20_eventlog(ctx, user, realm, session_id,
- "No MAC address in DevDetail", NULL);
- }
-
- if (user)
- db_update_mo(ctx, user, realm, "devdetail", devdetail);
-
- if (user)
- mo = spp_get_mo(ctx, node, URN_HS20_PPS, &valid, &err);
- else {
- mo = NULL;
- err = NULL;
- }
- if (user && mo) {
- hs20_eventlog_node(ctx, user, realm, session_id,
- "Received PPS MO", mo);
- if (valid == 0) {
- hs20_eventlog(ctx, user, realm, session_id,
- "OMA-DM DDF DTD validation errors "
- "in PPS MO", err);
- xml_node_get_attr_value_free(ctx->xml, redirect_uri);
- os_free(err);
- return build_post_dev_data_response(
- ctx, NULL, session_id,
- "Error occurred", "Other");
- }
- db_update_mo(ctx, user, realm, "pps", mo);
- db_update_val(ctx, user, realm, "fetch_pps", "0", dmacc);
- xml_node_free(ctx->xml, mo);
- }
- os_free(err);
-
- if (user && !mo) {
- char *fetch;
- int fetch_pps;
-
- fetch = db_get_val(ctx, user, realm, "fetch_pps", dmacc);
- fetch_pps = fetch ? atoi(fetch) : 0;
- free(fetch);
-
- if (fetch_pps) {
- enum hs20_session_operation oper;
- if (strcasecmp(req_reason, "Subscription remediation")
- == 0)
- oper = CONTINUE_SUBSCRIPTION_REMEDIATION;
- else if (strcasecmp(req_reason, "Policy update") == 0)
- oper = CONTINUE_POLICY_UPDATE;
- else
- oper = NO_OPERATION;
- if (db_add_session(ctx, user, realm, session_id, NULL,
- NULL, oper, NULL) < 0)
- goto out;
-
- ret = spp_exec_upload_mo(ctx, session_id,
- URN_HS20_PPS);
- hs20_eventlog_node(ctx, user, realm, session_id,
- "request PPS MO upload",
- ret);
- goto out;
- }
- }
-
- if (user && strcasecmp(req_reason, "MO upload") == 0) {
- char *val = db_get_session_val(ctx, user, realm, session_id,
- "operation");
- enum hs20_session_operation oper;
- if (!val) {
- debug_print(ctx, 1, "No session %s found to continue",
- session_id);
- goto out;
- }
- oper = atoi(val);
- free(val);
- if (oper == CONTINUE_SUBSCRIPTION_REMEDIATION)
- req_reason = "Subscription remediation";
- else if (oper == CONTINUE_POLICY_UPDATE)
- req_reason = "Policy update";
- else {
- debug_print(ctx, 1,
- "No pending operation in session %s",
- session_id);
- goto out;
- }
- }
-
- if (strcasecmp(req_reason, "Subscription registration") == 0) {
- ret = hs20_subscription_registration(ctx, realm, session_id,
- redirect_uri,
- wifi_mac_addr);
- hs20_eventlog_node(ctx, user, realm, session_id,
- "subscription registration response",
- ret);
- goto out;
- }
- if (user && strcasecmp(req_reason, "Subscription remediation") == 0) {
- ret = hs20_subscription_remediation(ctx, user, realm,
- session_id, dmacc,
- redirect_uri);
- hs20_eventlog_node(ctx, user, realm, session_id,
- "subscription remediation response",
- ret);
- goto out;
- }
- if (user && strcasecmp(req_reason, "Policy update") == 0) {
- ret = hs20_policy_update(ctx, user, realm, session_id, dmacc);
- hs20_eventlog_node(ctx, user, realm, session_id,
- "policy update response",
- ret);
- goto out;
- }
-
- if (strcasecmp(req_reason, "User input completed") == 0) {
- db_add_session_devinfo(ctx, session_id, devinfo);
- db_add_session_devdetail(ctx, session_id, devdetail);
- ret = hs20_user_input_complete(ctx, user, realm, dmacc,
- session_id);
- hs20_eventlog_node(ctx, user, realm, session_id,
- "user input completed response", ret);
- goto out;
- }
-
- if (strcasecmp(req_reason, "Certificate enrollment completed") == 0) {
- ret = hs20_cert_enroll_completed(ctx, user, realm, dmacc,
- session_id);
- hs20_eventlog_node(ctx, user, realm, session_id,
- "certificate enrollment response", ret);
- goto out;
- }
-
- if (strcasecmp(req_reason, "Certificate enrollment failed") == 0) {
- ret = hs20_cert_enroll_failed(ctx, user, realm, dmacc,
- session_id);
- hs20_eventlog_node(ctx, user, realm, session_id,
- "certificate enrollment failed response",
- ret);
- goto out;
- }
-
- if (strcasecmp(req_reason, "Subscription provisioning") == 0) {
- ret = hs20_sim_provisioning(ctx, user, realm, dmacc,
- session_id);
- hs20_eventlog_node(ctx, user, realm, session_id,
- "subscription provisioning response",
- ret);
- goto out;
- }
-
- debug_print(ctx, 1, "Unsupported requestReason '%s' user '%s'",
- req_reason, user);
-out:
- xml_node_get_attr_value_free(ctx->xml, req_reason_buf);
- xml_node_get_attr_value_free(ctx->xml, redirect_uri);
- if (devinfo)
- xml_node_free(ctx->xml, devinfo);
- if (devdetail)
- xml_node_free(ctx->xml, devdetail);
- return ret;
-}
-
-
-static xml_node_t * build_spp_exchange_complete(struct hs20_svc *ctx,
- const char *session_id,
- const char *status,
- const char *error_code)
-{
- xml_namespace_t *ns;
- xml_node_t *spp_node, *node;
-
- spp_node = xml_node_create_root(ctx->xml, SPP_NS_URI, "spp", &ns,
- "sppExchangeComplete");
-
-
- xml_node_add_attr(ctx->xml, spp_node, ns, "sppVersion", "1.0");
- xml_node_add_attr(ctx->xml, spp_node, ns, "sessionID", session_id);
- xml_node_add_attr(ctx->xml, spp_node, ns, "sppStatus", status);
-
- if (error_code) {
- node = xml_node_create(ctx->xml, spp_node, ns, "sppError");
- xml_node_add_attr(ctx->xml, node, NULL, "errorCode",
- error_code);
- }
-
- return spp_node;
-}
-
-
-static int add_subscription(struct hs20_svc *ctx, const char *session_id)
-{
- char *user, *realm, *pw, *pw_mm, *pps, *str;
- char *osu_user, *osu_password, *eap_method;
- char *policy = NULL;
- char *sql;
- int ret = -1;
- char *free_account;
- int free_acc;
- char *type;
- int cert = 0;
- char *cert_pem, *fingerprint;
- const char *method;
-
- user = db_get_session_val(ctx, NULL, NULL, session_id, "user");
- realm = db_get_session_val(ctx, NULL, NULL, session_id, "realm");
- pw = db_get_session_val(ctx, NULL, NULL, session_id, "password");
- pw_mm = db_get_session_val(ctx, NULL, NULL, session_id,
- "machine_managed");
- pps = db_get_session_val(ctx, NULL, NULL, session_id, "pps");
- cert_pem = db_get_session_val(ctx, NULL, NULL, session_id, "cert_pem");
- fingerprint = db_get_session_val(ctx, NULL, NULL, session_id, "cert");
- type = db_get_session_val(ctx, NULL, NULL, session_id, "type");
- if (type && strcmp(type, "cert") == 0)
- cert = 1;
- free(type);
- osu_user = db_get_session_val(ctx, NULL, NULL, session_id, "osu_user");
- osu_password = db_get_session_val(ctx, NULL, NULL, session_id,
- "osu_password");
- eap_method = db_get_session_val(ctx, NULL, NULL, session_id,
- "eap_method");
-
- if (!user || !realm || !pw) {
- debug_print(ctx, 1, "Could not find session info from DB for "
- "the new subscription");
- goto out;
- }
-
- free_account = db_get_osu_config_val(ctx, realm, "free_account");
- free_acc = free_account && strcmp(free_account, user) == 0;
- free(free_account);
-
- policy = db_get_osu_config_val(ctx, realm, "sim_policy");
-
- debug_print(ctx, 1,
- "New subscription: user='%s' realm='%s' free_acc=%d",
- user, realm, free_acc);
- debug_print(ctx, 1, "New subscription: pps='%s'", pps);
-
- sql = sqlite3_mprintf("UPDATE eventlog SET user=%Q, realm=%Q WHERE "
- "sessionid=%Q AND (user='' OR user IS NULL)",
- user, realm, session_id);
- if (sql) {
- debug_print(ctx, 1, "DB: %s", sql);
- if (sqlite3_exec(ctx->db, sql, NULL, NULL, NULL) != SQLITE_OK) {
- debug_print(ctx, 1, "Failed to update eventlog in "
- "sqlite database: %s",
- sqlite3_errmsg(ctx->db));
- }
- sqlite3_free(sql);
- }
-
- if (free_acc) {
- hs20_eventlog(ctx, user, realm, session_id,
- "completed shared free account registration",
- NULL);
- ret = 0;
- goto out;
- }
-
- str = db_get_session_val(ctx, NULL, NULL, session_id, "mac_addr");
-
- if (eap_method && eap_method[0])
- method = eap_method;
- else
- method = cert ? "TLS" : "TTLS-MSCHAPV2";
- sql = sqlite3_mprintf("INSERT INTO users(identity,realm,phase2,methods,cert,cert_pem,machine_managed,mac_addr,osu_user,osu_password,policy) VALUES (%Q,%Q,%d,%Q,%Q,%Q,%d,%Q,%Q,%Q,%Q)",
- user, realm, cert ? 0 : 1,
- method,
- fingerprint ? fingerprint : "",
- cert_pem ? cert_pem : "",
- pw_mm && atoi(pw_mm) ? 1 : 0,
- str ? str : "",
- osu_user ? osu_user : "",
- osu_password ? osu_password : "",
- policy ? policy : "");
- free(str);
- if (sql == NULL)
- goto out;
- debug_print(ctx, 1, "DB: %s", sql);
- if (sqlite3_exec(ctx->db, sql, NULL, NULL, NULL) != SQLITE_OK) {
- debug_print(ctx, 1, "Failed to add user in sqlite database: %s",
- sqlite3_errmsg(ctx->db));
- sqlite3_free(sql);
- goto out;
- }
- sqlite3_free(sql);
-
- if (cert)
- ret = 0;
- else
- ret = update_password(ctx, user, realm, pw, 0);
- if (ret < 0) {
- sql = sqlite3_mprintf("DELETE FROM users WHERE identity=%Q AND realm=%Q AND (phase2=1 OR methods='TLS')",
- user, realm);
- if (sql) {
- debug_print(ctx, 1, "DB: %s", sql);
- sqlite3_exec(ctx->db, sql, NULL, NULL, NULL);
- sqlite3_free(sql);
- }
- }
-
- if (pps)
- db_update_mo_str(ctx, user, realm, "pps", pps);
-
- str = db_get_session_val(ctx, NULL, NULL, session_id, "devinfo");
- if (str) {
- db_update_mo_str(ctx, user, realm, "devinfo", str);
- free(str);
- }
-
- str = db_get_session_val(ctx, NULL, NULL, session_id, "devdetail");
- if (str) {
- db_update_mo_str(ctx, user, realm, "devdetail", str);
- free(str);
- }
-
- if (cert && user) {
- const char *serialnum;
-
- str = db_get_session_val(ctx, NULL, NULL, session_id,
- "mac_addr");
-
- if (os_strncmp(user, "cert-", 5) == 0)
- serialnum = user + 5;
- else
- serialnum = "";
- sql = sqlite3_mprintf("INSERT OR REPLACE INTO cert_enroll (mac_addr,user,realm,serialnum) VALUES(%Q,%Q,%Q,%Q)",
- str ? str : "", user, realm ? realm : "",
- serialnum);
- free(str);
- if (sql) {
- debug_print(ctx, 1, "DB: %s", sql);
- if (sqlite3_exec(ctx->db, sql, NULL, NULL, NULL) !=
- SQLITE_OK) {
- debug_print(ctx, 1,
- "Failed to add cert_enroll entry into sqlite database: %s",
- sqlite3_errmsg(ctx->db));
- }
- sqlite3_free(sql);
- }
- }
-
- str = db_get_session_val(ctx, NULL, NULL, session_id,
- "mobile_identifier_hash");
- if (str) {
- sql = sqlite3_mprintf("DELETE FROM sim_provisioning WHERE mobile_identifier_hash=%Q",
- str);
- if (sql) {
- debug_print(ctx, 1, "DB: %s", sql);
- if (sqlite3_exec(ctx->db, sql, NULL, NULL, NULL) !=
- SQLITE_OK) {
- debug_print(ctx, 1,
- "Failed to delete pending sim_provisioning entry: %s",
- sqlite3_errmsg(ctx->db));
- }
- sqlite3_free(sql);
- }
- os_free(str);
- }
-
- if (ret == 0) {
- hs20_eventlog(ctx, user, realm, session_id,
- "completed subscription registration", NULL);
- }
-
-out:
- free(user);
- free(realm);
- free(pw);
- free(pw_mm);
- free(pps);
- free(cert_pem);
- free(fingerprint);
- free(osu_user);
- free(osu_password);
- free(eap_method);
- os_free(policy);
- return ret;
-}
-
-
-static xml_node_t * hs20_spp_update_response(struct hs20_svc *ctx,
- xml_node_t *node,
- const char *user,
- const char *realm,
- const char *session_id,
- int dmacc)
-{
- char *status;
- xml_node_t *ret;
- char *val;
- enum hs20_session_operation oper;
-
- status = xml_node_get_attr_value_ns(ctx->xml, node, SPP_NS_URI,
- "sppStatus");
- if (status == NULL) {
- debug_print(ctx, 1, "No sppStatus attribute");
- return NULL;
- }
-
- debug_print(ctx, 1, "sppUpdateResponse: sppStatus: %s sessionID: %s",
- status, session_id);
-
- val = db_get_session_val(ctx, NULL, NULL, session_id, "operation");
- if (!val) {
- debug_print(ctx, 1,
- "No session active for sessionID: %s",
- session_id);
- oper = NO_OPERATION;
- } else
- oper = atoi(val);
-
- if (strcasecmp(status, "OK") == 0) {
- char *new_pw = NULL;
-
- xml_node_get_attr_value_free(ctx->xml, status);
-
- if (oper == USER_REMEDIATION) {
- new_pw = db_get_session_val(ctx, user, realm,
- session_id, "password");
- if (new_pw == NULL || strlen(new_pw) == 0) {
- free(new_pw);
- ret = build_spp_exchange_complete(
- ctx, session_id, "Error occurred",
- "Other");
- hs20_eventlog_node(ctx, user, realm,
- session_id, "No password "
- "had been assigned for "
- "session", ret);
- db_remove_session(ctx, user, realm, session_id);
- return ret;
- }
- oper = UPDATE_PASSWORD;
- }
- if (oper == UPDATE_PASSWORD) {
- if (!new_pw) {
- new_pw = db_get_session_val(ctx, user, realm,
- session_id,
- "password");
- if (!new_pw) {
- db_remove_session(ctx, user, realm,
- session_id);
- return NULL;
- }
- }
- debug_print(ctx, 1, "Update user '%s' password in DB",
- user);
- if (update_password(ctx, user, realm, new_pw, dmacc) <
- 0) {
- debug_print(ctx, 1, "Failed to update user "
- "'%s' password in DB", user);
- ret = build_spp_exchange_complete(
- ctx, session_id, "Error occurred",
- "Other");
- hs20_eventlog_node(ctx, user, realm,
- session_id, "Failed to "
- "update database", ret);
- db_remove_session(ctx, user, realm, session_id);
- return ret;
- }
- hs20_eventlog(ctx, user, realm,
- session_id, "Updated user password "
- "in database", NULL);
- }
- if (oper == CLEAR_REMEDIATION) {
- debug_print(ctx, 1,
- "Clear remediation requirement for user '%s' in DB",
- user);
- if (clear_remediation(ctx, user, realm, dmacc) < 0) {
- debug_print(ctx, 1,
- "Failed to clear remediation requirement for user '%s' in DB",
- user);
- ret = build_spp_exchange_complete(
- ctx, session_id, "Error occurred",
- "Other");
- hs20_eventlog_node(ctx, user, realm,
- session_id,
- "Failed to update database",
- ret);
- db_remove_session(ctx, user, realm, session_id);
- return ret;
- }
- hs20_eventlog(ctx, user, realm,
- session_id,
- "Cleared remediation requirement in database",
- NULL);
- }
- if (oper == SUBSCRIPTION_REGISTRATION) {
- if (add_subscription(ctx, session_id) < 0) {
- debug_print(ctx, 1, "Failed to add "
- "subscription into DB");
- ret = build_spp_exchange_complete(
- ctx, session_id, "Error occurred",
- "Other");
- hs20_eventlog_node(ctx, user, realm,
- session_id, "Failed to "
- "update database", ret);
- db_remove_session(ctx, user, realm, session_id);
- return ret;
- }
- }
- if (oper == POLICY_REMEDIATION || oper == POLICY_UPDATE) {
- char *val;
- val = db_get_val(ctx, user, realm, "remediation",
- dmacc);
- if (val && strcmp(val, "policy") == 0)
- db_update_val(ctx, user, realm, "remediation",
- "", dmacc);
- free(val);
- }
- if (oper == POLICY_UPDATE)
- db_update_val(ctx, user, realm, "polupd_done", "1",
- dmacc);
- if (oper == CERT_REENROLL) {
- char *new_user;
- char event[200];
-
- new_user = db_get_session_val(ctx, NULL, NULL,
- session_id, "user");
- if (!new_user) {
- debug_print(ctx, 1,
- "Failed to find new user name (cert-serialnum)");
- ret = build_spp_exchange_complete(
- ctx, session_id, "Error occurred",
- "Other");
- hs20_eventlog_node(ctx, user, realm,
- session_id,
- "Failed to find new user name (cert reenroll)",
- ret);
- db_remove_session(ctx, NULL, NULL, session_id);
- return ret;
- }
-
- debug_print(ctx, 1,
- "Update certificate user entry to use the new serial number (old=%s new=%s)",
- user, new_user);
- os_snprintf(event, sizeof(event), "renamed user to: %s",
- new_user);
- hs20_eventlog(ctx, user, realm, session_id, event,
- NULL);
-
- if (db_update_val(ctx, user, realm, "identity",
- new_user, 0) < 0 ||
- db_update_val(ctx, new_user, realm, "remediation",
- "", 0) < 0) {
- debug_print(ctx, 1,
- "Failed to update user name (cert-serialnum)");
- ret = build_spp_exchange_complete(
- ctx, session_id, "Error occurred",
- "Other");
- hs20_eventlog_node(ctx, user, realm,
- session_id,
- "Failed to update user name (cert reenroll)",
- ret);
- db_remove_session(ctx, NULL, NULL, session_id);
- os_free(new_user);
- return ret;
- }
-
- os_free(new_user);
- }
- ret = build_spp_exchange_complete(
- ctx, session_id,
- "Exchange complete, release TLS connection", NULL);
- hs20_eventlog_node(ctx, user, realm, session_id,
- "Exchange completed", ret);
- db_remove_session(ctx, NULL, NULL, session_id);
- return ret;
- }
-
- ret = build_spp_exchange_complete(ctx, session_id, "Error occurred",
- "Other");
- hs20_eventlog_node(ctx, user, realm, session_id, "Error occurred", ret);
- db_remove_session(ctx, user, realm, session_id);
- xml_node_get_attr_value_free(ctx->xml, status);
- return ret;
-}
-
-
-#define SPP_SESSION_ID_LEN 16
-
-static char * gen_spp_session_id(void)
-{
- FILE *f;
- int i;
- char *session;
-
- session = os_malloc(SPP_SESSION_ID_LEN * 2 + 1);
- if (session == NULL)
- return NULL;
-
- f = fopen("/dev/urandom", "r");
- if (f == NULL) {
- os_free(session);
- return NULL;
- }
- for (i = 0; i < SPP_SESSION_ID_LEN; i++)
- os_snprintf(session + i * 2, 3, "%02x", fgetc(f));
-
- fclose(f);
- return session;
-}
-
-xml_node_t * hs20_spp_server_process(struct hs20_svc *ctx, xml_node_t *node,
- const char *auth_user,
- const char *auth_realm, int dmacc)
-{
- xml_node_t *ret = NULL;
- char *session_id;
- const char *op_name;
- char *xml_err;
- char fname[200];
-
- debug_dump_node(ctx, "received request", node);
-
- if (!dmacc && auth_user && auth_realm) {
- char *real;
- real = db_get_val(ctx, auth_user, auth_realm, "identity", 0);
- if (!real) {
- real = db_get_val(ctx, auth_user, auth_realm,
- "identity", 1);
- if (real)
- dmacc = 1;
- }
- os_free(real);
- }
-
- snprintf(fname, sizeof(fname), "%s/spp/spp.xsd", ctx->root_dir);
- if (xml_validate(ctx->xml, node, fname, &xml_err) < 0) {
- /*
- * We may not be able to extract the sessionID from invalid
- * input, but well, we can try.
- */
- session_id = xml_node_get_attr_value_ns(ctx->xml, node,
- SPP_NS_URI,
- "sessionID");
- debug_print(ctx, 1,
- "SPP message failed validation, xsd file: %s xml-error: %s",
- fname, xml_err);
- hs20_eventlog_node(ctx, auth_user, auth_realm, session_id,
- "SPP message failed validation", node);
- hs20_eventlog(ctx, auth_user, auth_realm, session_id,
- "Validation errors", xml_err);
- os_free(xml_err);
- xml_node_get_attr_value_free(ctx->xml, session_id);
- /* TODO: what to return here? */
- ret = xml_node_create_root(ctx->xml, NULL, NULL, NULL,
- "SppValidationError");
- return ret;
- }
-
- session_id = xml_node_get_attr_value_ns(ctx->xml, node, SPP_NS_URI,
- "sessionID");
- if (session_id) {
- char *tmp;
- debug_print(ctx, 1, "Received sessionID %s", session_id);
- tmp = os_strdup(session_id);
- xml_node_get_attr_value_free(ctx->xml, session_id);
- if (tmp == NULL)
- return NULL;
- session_id = tmp;
- } else {
- session_id = gen_spp_session_id();
- if (session_id == NULL) {
- debug_print(ctx, 1, "Failed to generate sessionID");
- return NULL;
- }
- debug_print(ctx, 1, "Generated sessionID %s", session_id);
- }
-
- op_name = xml_node_get_localname(ctx->xml, node);
- if (op_name == NULL) {
- debug_print(ctx, 1, "Could not get op_name");
- return NULL;
- }
-
- if (strcmp(op_name, "sppPostDevData") == 0) {
- hs20_eventlog_node(ctx, auth_user, auth_realm, session_id,
- "sppPostDevData received and validated",
- node);
- ret = hs20_spp_post_dev_data(ctx, node, auth_user, auth_realm,
- session_id, dmacc);
- } else if (strcmp(op_name, "sppUpdateResponse") == 0) {
- hs20_eventlog_node(ctx, auth_user, auth_realm, session_id,
- "sppUpdateResponse received and validated",
- node);
- ret = hs20_spp_update_response(ctx, node, auth_user,
- auth_realm, session_id, dmacc);
- } else {
- hs20_eventlog_node(ctx, auth_user, auth_realm, session_id,
- "Unsupported SPP message received and "
- "validated", node);
- debug_print(ctx, 1, "Unsupported operation '%s'", op_name);
- /* TODO: what to return here? */
- ret = xml_node_create_root(ctx->xml, NULL, NULL, NULL,
- "SppUnknownCommandError");
- }
- os_free(session_id);
-
- if (ret == NULL) {
- /* TODO: what to return here? */
- ret = xml_node_create_root(ctx->xml, NULL, NULL, NULL,
- "SppInternalError");
- }
-
- return ret;
-}
-
-
-int hs20_spp_server_init(struct hs20_svc *ctx)
-{
- char fname[200];
- ctx->db = NULL;
- snprintf(fname, sizeof(fname), "%s/AS/DB/eap_user.db", ctx->root_dir);
- if (sqlite3_open(fname, &ctx->db)) {
- printf("Failed to open sqlite database: %s\n",
- sqlite3_errmsg(ctx->db));
- sqlite3_close(ctx->db);
- return -1;
- }
-
- return 0;
-}
-
-
-void hs20_spp_server_deinit(struct hs20_svc *ctx)
-{
- sqlite3_close(ctx->db);
- ctx->db = NULL;
-}
diff --git a/hs20/server/spp_server.h b/hs20/server/spp_server.h
deleted file mode 100644
index 421974c607..0000000000
--- a/hs20/server/spp_server.h
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * Hotspot 2.0 SPP server
- * Copyright (c) 2012-2013, Qualcomm Atheros, Inc.
- *
- * This software may be distributed under the terms of the BSD license.
- * See README for more details.
- */
-
-#ifndef SPP_SERVER_H
-#define SPP_SERVER_H
-
-struct hs20_svc {
- const void *ctx;
- struct xml_node_ctx *xml;
- char *root_dir;
- FILE *debug_log;
- sqlite3 *db;
- const char *addr;
- const char *test;
- const char *imsi;
- const char *eap_method;
- const char *id_hash;
-};
-
-
-void debug_print(struct hs20_svc *ctx, int print, const char *fmt, ...)
- __attribute__ ((format (printf, 3, 4)));
-void debug_dump_node(struct hs20_svc *ctx, const char *title, xml_node_t *node);
-
-xml_node_t * hs20_spp_server_process(struct hs20_svc *ctx, xml_node_t *node,
- const char *auth_user,
- const char *auth_realm, int dmacc);
-int hs20_spp_server_init(struct hs20_svc *ctx);
-void hs20_spp_server_deinit(struct hs20_svc *ctx);
-
-#endif /* SPP_SERVER_H */
diff --git a/hs20/server/sql-example.txt b/hs20/server/sql-example.txt
deleted file mode 100644
index 20dcf2f5c6..0000000000
--- a/hs20/server/sql-example.txt
+++ /dev/null
@@ -1,17 +0,0 @@
-INSERT INTO osu_config(realm,field,value) VALUES('example.com','fqdn','example.com');
-INSERT INTO osu_config(realm,field,value) VALUES('example.com','friendly_name','Example Operator');
-INSERT INTO osu_config(realm,field,value) VALUES('example.com','spp_http_auth_url','https://subscription-server.osu.example.com/hs20/spp.php?realm=example.com');
-INSERT INTO osu_config(realm,field,value) VALUES('example.com','trust_root_cert_url','https://osu-server.osu.example.com/hs20/files/spp-root-ca.der');
-INSERT INTO osu_config(realm,field,value) VALUES('example.com','trust_root_cert_fingerprint','5b393a9246865569485c2605c3304e48212b449367858299beba9384c4cf4647');
-INSERT INTO osu_config(realm,field,value) VALUES('example.com','aaa_trust_root_cert_url','https://osu-server.osu.example.com/hs20/files/aaa-root-ca.der');
-INSERT INTO osu_config(realm,field,value) VALUES('example.com','aaa_trust_root_cert_fingerprint','5b393a9246865569485c2605c3304e48212b449367858299beba9384c4cf4647');
-INSERT INTO osu_config(realm,field,value) VALUES('example.com','free_account','free');
-INSERT INTO osu_config(realm,field,value) VALUES('example.com','policy_url','https://subscription-server.osu.example.com/hs20/spp.php?realm=example.com');
-INSERT INTO osu_config(realm,field,value) VALUES('example.com','remediation_url','https://subscription-server.osu.example.com/hs20/remediation.php?session_id=');
-INSERT INTO osu_config(realm,field,value) VALUES('example.com','free_remediation_url','https://subscription-server.osu.example.com/hs20/free-remediation.php?session_id=');
-INSERT INTO osu_config(realm,field,value) VALUES('example.com','signup_url','https://subscription-server.osu.example.com/hs20/signup.php?session_id=');
-
-
-INSERT INTO users(identity,realm,methods,password,phase2,shared) VALUES('free','example.com','TTLS-MSCHAPV2','free',1,1);
-
-INSERT INTO wildcards(identity,methods) VALUES('','TTLS,TLS');
diff --git a/hs20/server/sql.txt b/hs20/server/sql.txt
deleted file mode 100644
index 2cc6edea40..0000000000
--- a/hs20/server/sql.txt
+++ /dev/null
@@ -1,108 +0,0 @@
-CREATE TABLE eventlog(
- user TEXT,
- realm TEXT,
- sessionid TEXT COLLATE NOCASE,
- timestamp TEXT,
- notes TEXT,
- dump TEXT,
- addr TEXT
-);
-
-CREATE TABLE sessions(
- timestamp TEXT,
- id TEXT COLLATE NOCASE,
- user TEXT,
- realm TEXT,
- password TEXT,
- machine_managed BOOLEAN,
- operation INTEGER,
- type TEXT,
- pps TEXT,
- redirect_uri TEXT,
- devinfo TEXT,
- devdetail TEXT,
- cert TEXT,
- cert_pem TEXT,
- mac_addr TEXT,
- osu_user TEXT,
- osu_password TEXT,
- eap_method TEXT,
- mobile_identifier_hash TEXT,
- test TEXT
-);
-
-CREATE index sessions_id_index ON sessions(id);
-
-CREATE TABLE osu_config(
- realm TEXT,
- field TEXT,
- value TEXT
-);
-
-CREATE TABLE users(
- identity TEXT PRIMARY KEY,
- methods TEXT,
- password TEXT,
- machine_managed BOOLEAN,
- remediation TEXT,
- phase2 INTEGER,
- realm TEXT,
- policy TEXT,
- devinfo TEXT,
- devdetail TEXT,
- pps TEXT,
- fetch_pps INTEGER,
- osu_user TEXT,
- osu_password TEXT,
- shared INTEGER,
- cert TEXT,
- cert_pem TEXT,
- t_c_timestamp INTEGER,
- mac_addr TEXT,
- last_msk TEXT,
- polupd_done TEXT,
- subrem TEXT
-);
-
-CREATE TABLE wildcards(
- identity TEXT PRIMARY KEY,
- methods TEXT
-);
-
-CREATE TABLE authlog(
- timestamp TEXT,
- session TEXT,
- nas_ip TEXT,
- username TEXT,
- note TEXT
-);
-
-CREATE TABLE pending_tc(
- mac_addr TEXT PRIMARY KEY,
- identity TEXT
-);
-
-CREATE TABLE current_sessions(
- mac_addr TEXT PRIMARY KEY,
- identity TEXT,
- start_time TEXT,
- nas TEXT,
- hs20_t_c_filtering BOOLEAN,
- waiting_coa_ack BOOLEAN,
- coa_ack_received BOOLEAN
-);
-
-CREATE TABLE cert_enroll(
- mac_addr TEXT PRIMARY KEY,
- user TEXT,
- realm TEXT,
- serialnum TEXT
-);
-
-CREATE TABLE sim_provisioning(
- mobile_identifier_hash TEXT PRIMARY KEY,
- imsi TEXT,
- mac_addr TEXT,
- eap_method TEXT,
- timestamp TEXT
-);
diff --git a/hs20/server/www/add-free.php b/hs20/server/www/add-free.php
deleted file mode 100644
index 1efc655632..0000000000
--- a/hs20/server/www/add-free.php
+++ /dev/null
@@ -1,50 +0,0 @@
-query("SELECT rowid,* FROM sessions WHERE id='$id'")->fetch();
-if ($row == false) {
- die("Session not found");
-}
-
-$uri = $row['redirect_uri'];
-$rowid = $row['rowid'];
-$realm = $row['realm'];
-
-$row = $db->query("SELECT value FROM osu_config WHERE realm='$realm' AND field='free_account'")->fetch();
-if (!$row || strlen($row['value']) == 0) {
- die("Free account disabled");
-}
-
-$user = $row['value'];
-
-$row = $db->query("SELECT password FROM users WHERE identity='$user' AND realm='$realm'")->fetch();
-if (!$row)
- die("Free account not found");
-
-$pw = $row['password'];
-
-if (!$db->exec("UPDATE sessions SET user='$user', password='$pw', realm='$realm', machine_managed='1' WHERE rowid=$rowid")) {
- die("Failed to update session database");
-}
-
-$db->exec("INSERT INTO eventlog(user,realm,sessionid,timestamp,notes) " .
- "VALUES ('$user', '$realm', '$id', " .
- "strftime('%Y-%m-%d %H:%M:%f','now'), " .
- "'completed user input response for a new PPS MO')");
-
-header("Location: $uri", true, 302);
-
-?>
diff --git a/hs20/server/www/add-mo.php b/hs20/server/www/add-mo.php
deleted file mode 100644
index a3b4513531..0000000000
--- a/hs20/server/www/add-mo.php
+++ /dev/null
@@ -1,56 +0,0 @@
-Invalid username
\n";
- echo "Try again\n";
- echo "