diff options
Diffstat (limited to 'hs20/server')
34 files changed, 0 insertions, 5454 deletions
diff --git a/hs20/server/.gitignore b/hs20/server/.gitignore deleted file mode 100644 index fecb096c128a..000000000000 --- 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 0cab6d6b010a..000000000000 --- 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 c72dcbda45e9..000000000000 --- 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 b50ea00d0b77..000000000000 --- 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 0b73a0408284..000000000000 --- 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 a829ff29bf44..000000000000 --- 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 931a20696d02..000000000000 --- 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 116c6e1c3d01..000000000000 --- 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 620947d01af0..000000000000 --- 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 f2b23250cadd..000000000000 --- 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 5bc50be1dbc9..000000000000 --- 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 61410138340f..000000000000 --- 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 78abcccff455..000000000000 --- 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 <<EOF -Usage:\n -# -c: Company name, used to generate Subject name CN for Intermediate CA\n -# -C: Subject name CN of the Root CA ($CNR)\n -# -D: Enable debugging (set -x, etc)\n -# -g: Logo sha1 hash ($LOGO_HASH1)\n -# -G: Logo sha256 hash ($LOGO_HASH256)\n -# -h: Show this help message\n -# -l: Logo URI ($LOGO_URI)\n -# -m: Domain ($DOMAIN)\n -# -o: Subject name CN for OSU-Client Server ($CNOC)\n -# -O: Subject name CN for OCSP Server ($CNO)\n -# -p: passphrase for private keys ($PASS)\n -# -r: Operator-english ($OPER_ENG)\n -# -R: Operator-finish ($OPER_FI)\n -# -S: OSU Server name ($OSU_SERVER_HOSTNAME)\n -# -u: OCSP-URI ($OCSP_URI)\n -# -V: Subject name CN for OSU-Revoked Server ($CNV)\n -EOF -) - -while getopts "c:C:Dg:G:l:m:o:O:p:r:R:S:u:V:h" flag - do - case $flag in - c) COMPANY=$OPTARG;; - C) CNR=$OPTARG;; - D) DEBUG=1;; - g) LOGO_HASH1=$OPTARG;; - G) LOGO_HASH256=$OPTARG;; - h) echo -e $USAGE; exit 0;; - l) LOGO_URI=$OPTARG;; - m) DOMAIN=$OPTARG;; - o) CNOC=$OPTARG;; - O) CNO=$OPTARG;; - p) PASS=$OPTARG;; - r) OPER_ENG=$OPTARG;; - R) OPER_FI=$OPTARG;; - S) OSU_SERVER_HOSTNAME=$OPTARG;; - u) OCSP_URI=$OPTARG;; - V) CNV=$OPTARG;; - *) echo "Unknown flag: $flag"; echo -e $USAGE; exit 1;; - esac -done - -fail() -{ - echo "$*" - exit 1 -} - -echo -echo "---[ Root CA ]----------------------------------------------------------" -echo - -if [ $DEBUG = 1 ] -then - set -x -fi - -# Set the passphrase and some other common config accordingly. -cat openssl-root.cnf | sed "s/@PASSWORD@/$PASS/" \ - > 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 Binary files differdeleted file mode 100644 index ac7c259fff2e..000000000000 --- a/hs20/server/ca/w1fi_logo.png +++ /dev/null diff --git a/hs20/server/hs20-osu-server.txt b/hs20/server/hs20-osu-server.txt deleted file mode 100644 index 22478ad9d2cb..000000000000 --- 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 <<EOF -CONFIG_DRIVER_NONE=y -CONFIG_PKCS12=y -CONFIG_RADIUS_SERVER=y -CONFIG_EAP=y -CONFIG_EAP_TLS=y -CONFIG_EAP_MSCHAPV2=y -CONFIG_EAP_PEAP=y -CONFIG_EAP_GTC=y -CONFIG_EAP_TTLS=y -CONFIG_EAP_SIM=y -CONFIG_EAP_AKA=y -CONFIG_EAP_AKA_PRIME=y -CONFIG_SQLITE=y -CONFIG_HS20=y -EOF - -make hostapd hlr_auc_gw -cp hostapd hlr_auc_gw /home/user/hs20-server/AS - -# build hs20_spp_server -cd ../hs20/server -make clean -make -cp hs20_spp_server /home/user/hs20-server/spp -# prepare database (web server user/group needs to have write access) -mkdir -p /home/user/hs20-server/AS/DB -sudo chgrp www-data /home/user/hs20-server/AS/DB -sudo chmod g+w /home/user/hs20-server/AS/DB -sqlite3 /home/user/hs20-server/AS/DB/eap_user.db < sql.txt -sudo chgrp www-data /home/user/hs20-server/AS/DB/eap_user.db -sudo chmod g+w /home/user/hs20-server/AS/DB/eap_user.db -# add example configuration (note: need to update URLs to match the system) -sqlite3 /home/user/hs20-server/AS/DB/eap_user.db < sql-example.txt - -# copy PHP scripts -# Modify config.php if different installation directory is used. -# Modify PHP scripts to get the desired behavior for user interaction (or use -# the examples as-is for initial testing). -cp -r www /home/user/hs20-server - -# Create /home/user/hs20-server/terms-and-conditions file (HTML segment to be -# inserted within the BODY section of the page). -cat > /home/user/hs20-server/terms-and-conditions <<EOF -<P>Terms and conditions..</P> -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 <<EOF -<Policy> - <PolicyUpdate> - <UpdateInterval>30</UpdateInterval> - <UpdateMethod>ClientInitiated</UpdateMethod> - <Restriction>Unrestricted</Restriction> - <URI>https://policy-server.osu.example.com/hs20/spp.php</URI> - </PolicyUpdate> -</Policy> -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 <<EOF -driver=none -radius_server_clients=as.radius_clients -eap_server=1 -eap_user_file=sqlite:DB/eap_user.db -ca_cert=Key/ca.pem -server_cert=Key/server.pem -private_key=Key/server.key -private_key_passwd=passphrase -eap_sim_db=unix:/tmp/hlr_auc_gw.sock db=eap_sim.db -subscr_remediation_url=https://subscription-server.osu.example.com/hs20/spp.php -EOF - -# Set RADIUS passphrase for the APs -# Note: Modify to match the setup -cat > /home/user/hs20-server/AS/as.radius_clients <<EOF -0.0.0.0/0 radius -EOF - - -Start RADIUS authentication server ----------------------------------- - -cd /home/user/hs20-server/AS -./hostapd -B as-sql.conf - - -OSEN RADIUS server configuration notes - -The OSEN RADIUS server config file should have the 'ocsp_stapling_response' -configuration in it. For example: - -# hostapd-radius config for the radius used by the OSEN AP -interface=eth0#0 -driver=none -logger_syslog=-1 -logger_syslog_level=2 -logger_stdout=-1 -logger_stdout_level=2 -ctrl_interface=/var/run/hostapd -ctrl_interface_group=0 -eap_server=1 -eap_user_file=/home/user/hs20-server/AS/hostapd-osen.eap_user -server_id=ben-ota-2-osen -radius_server_auth_port=1811 -radius_server_clients=/home/user/hs20-server/AS/hostap.radius_clients - -ca_cert=/home/user/hs20-server/ca/ca.pem -server_cert=/home/user/hs20-server/ca/server.pem -private_key=/home/user/hs20-server/ca/server.key -private_key_passwd=whatever - -ocsp_stapling_response=/home/user/hs20-server/ca/ocsp-server-cache.der - -The /home/user/hs20-server/AS/hostapd-osen.eap_user file should look -similar to this, and should coorelate with the osu_nai entry in -the non-OSEN VAP config file. For instance: - -# cat hostapd-osen.eap_user -# For OSEN authentication (Hotspot 2.0 Release 2) -"osen@w1.fi" WFA-UNAUTH-TLS - - -# Run OCSP server: -cd /home/user/hs20-server/ca -./ocsp-responder.sh& - -# Update cache (This should be run periodically) -./ocsp-update-cache.sh - - -Configure web server --------------------- - -Edit /etc/apache2/sites-available/default-ssl - -Add following block just before "SSL Engine Switch" line": - - Alias /hs20/ "/home/user/hs20-server/www/" - <Directory "/home/user/hs20-server/www/"> - Options Indexes MultiViews FollowSymLinks - AllowOverride None - Require all granted - SSLOptions +StdEnvVars - </Directory> - -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://<server>/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://<server>/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 347c40a73d6a..000000000000 --- 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 <time.h> -#include <sqlite3.h> - -#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<root directory> [-f<debug log>]\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 a50e9074f7b4..000000000000 --- a/hs20/server/spp_server.c +++ /dev/null @@ -1,2933 +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 <stdlib.h> -#include <stdio.h> -#include <string.h> -#include <ctype.h> -#include <time.h> -#include <errno.h> -#include <sqlite3.h> - -#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 == 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 421974c607b8..000000000000 --- 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 20dcf2f5c688..000000000000 --- 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 2cc6edea4063..000000000000 --- 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 1efc65563274..000000000000 --- a/hs20/server/www/add-free.php +++ /dev/null @@ -1,50 +0,0 @@ -<?php - -require('config.php'); - -$db = new PDO($osu_db); -if (!$db) { - die($sqliteerror); -} - -if (isset($_POST["id"])) - $id = preg_replace("/[^a-fA-F0-9]/", "", $_POST["id"]); -else - die("Missing session id"); -if (strlen($id) < 32) - die("Invalid session id"); - -$row = $db->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 a3b4513531f8..000000000000 --- a/hs20/server/www/add-mo.php +++ /dev/null @@ -1,56 +0,0 @@ -<?php - -require('config.php'); - -$db = new PDO($osu_db); -if (!$db) { - die($sqliteerror); -} - -if (isset($_POST["id"])) - $id = preg_replace("/[^a-fA-F0-9]/", "", $_POST["id"]); -else - die("Missing session id"); - -$user = $_POST["user"]; -$pw = $_POST["password"]; -if (strlen($id) < 32 || !isset($user) || !isset($pw)) { - die("Invalid POST data"); -} - -if (strlen($user) < 1 || strncasecmp($user, "cert-", 5) == 0) { - echo "<html><body><p><red>Invalid username</red></p>\n"; - echo "<a href=\"signup.php?session_id=$id\">Try again</a>\n"; - echo "</body></html>\n"; - exit; -} - -$row = $db->query("SELECT rowid,* FROM sessions WHERE id='$id'")->fetch(); -if ($row == false) { - die("Session not found"); -} -$realm = $row['realm']; - -$userrow = $db->query("SELECT identity FROM users WHERE identity='$user' AND realm='$realm'")->fetch(); -if ($userrow) { - echo "<html><body><p><red>Selected username is not available</red></p>\n"; - echo "<a href=\"signup.php?session_id=$id\">Try again</a>\n"; - echo "</body></html>\n"; - exit; -} - -$uri = $row['redirect_uri']; -$rowid = $row['rowid']; - -if (!$db->exec("UPDATE sessions SET user='$user', password='$pw', realm='$realm', type='password' 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/cert-enroll.php b/hs20/server/www/cert-enroll.php deleted file mode 100644 index f023ca5a5b03..000000000000 --- a/hs20/server/www/cert-enroll.php +++ /dev/null @@ -1,39 +0,0 @@ -<?php - -require('config.php'); - -$db = new PDO($osu_db); -if (!$db) { - die($sqliteerror); -} - -if (isset($_GET["id"])) - $id = preg_replace("/[^a-fA-F0-9]/", "", $_GET["id"]); -else - die("Missing session id"); -if (strlen($id) < 32) - die("Invalid session id"); - -$row = $db->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']; - -$user = sha1(mt_rand()); - -if (!$db->exec("UPDATE sessions SET user='$user', type='cert' WHERE rowid=$rowid")) { - die("Failed to update session database"); -} - -$db->exec("INSERT INTO eventlog(user,realm,sessionid,timestamp,notes) " . - "VALUES ('', '$realm', '$id', " . - "strftime('%Y-%m-%d %H:%M:%f','now'), " . - "'completed user input response for client certificate enrollment')"); - -header("Location: $uri", true, 302); - -?> diff --git a/hs20/server/www/config.php b/hs20/server/www/config.php deleted file mode 100644 index 4272b102a88c..000000000000 --- a/hs20/server/www/config.php +++ /dev/null @@ -1,7 +0,0 @@ -<?php -$osu_root = "/home/user/hs20-server"; -$osu_db = "sqlite:$osu_root/AS/DB/eap_user.db"; -$t_c_file = "$osu_root/terms-and-conditions"; -$t_c_timestamp = 123456789; -$hostapd_ctrl = "udg:///home/user/hs20-server/AS/ctrl/as" -?> diff --git a/hs20/server/www/est.php b/hs20/server/www/est.php deleted file mode 100644 index b7fb260d56c4..000000000000 --- a/hs20/server/www/est.php +++ /dev/null @@ -1,232 +0,0 @@ -<?php - -require('config.php'); - -$params = explode("/", $_SERVER["PATH_INFO"], 3); -$realm = $params[1]; -$cmd = $params[2]; -$method = $_SERVER["REQUEST_METHOD"]; - -unset($user); -unset($rowid); - -$db = new PDO($osu_db); -if (!$db) { - error_log("EST: Could not access database"); - die("Could not access database"); -} - -if (!empty($_SERVER['PHP_AUTH_DIGEST'])) { - $needed = array('nonce'=>1, 'nc'=>1, 'cnonce'=>1, 'qop'=>1, 'username'=>1, - 'uri'=>1, 'response'=>1); - $data = array(); - $keys = implode('|', array_keys($needed)); - preg_match_all('@(' . $keys . ')=(?:([\'"])([^\2]+?)\2|([^\s,]+))@', - $_SERVER['PHP_AUTH_DIGEST'], $matches, PREG_SET_ORDER); - foreach ($matches as $m) { - $data[$m[1]] = $m[3] ? $m[3] : $m[4]; - unset($needed[$m[1]]); - } - if ($needed) { - error_log("EST: Missing auth parameter"); - die('Authentication failed'); - } - $user = $data['username']; - if (strlen($user) < 1) { - error_log("EST: Empty username"); - die('Authentication failed'); - } - - $sql = "SELECT rowid,password,operation FROM sessions " . - "WHERE user='$user' AND realm='$realm'"; - $q = $db->query($sql); - if (!$q) { - error_log("EST: Session not found for user=$user realm=$realm"); - die("Session not found"); - } - $row = $q->fetch(); - if (!$row) { - error_log("EST: Session fetch failed for user=$user realm=$realm"); - die('Session not found'); - } - $rowid = $row['rowid']; - - $oper = $row['operation']; - if ($oper != '5') { - error_log("EST: Unexpected operation $oper for user=$user realm=$realm"); - die("Session not found"); - } - $pw = $row['password']; - if (strlen($pw) < 1) { - error_log("EST: Empty password for user=$user realm=$realm"); - die('Authentication failed'); - } - - $A1 = md5($user . ':' . $realm . ':' . $pw); - $A2 = md5($method . ':' . $data['uri']); - $resp = md5($A1 . ':' . $data['nonce'] . ':' . $data['nc'] . ':' . - $data['cnonce'] . ':' . $data['qop'] . ':' . $A2); - if ($data['response'] != $resp) { - error_log("EST: Incorrect authentication response for user=$user realm=$realm"); - die('Authentication failed'); - } -} else if (isset($_SERVER["SSL_CLIENT_VERIFY"]) && - $_SERVER["SSL_CLIENT_VERIFY"] == "SUCCESS" && - isset($_SERVER["SSL_CLIENT_M_SERIAL"])) { - $user = "cert-" . $_SERVER["SSL_CLIENT_M_SERIAL"]; - $sql = "SELECT rowid,password,operation FROM sessions " . - "WHERE user='$user' AND realm='$realm'"; - $q = $db->query($sql); - if (!$q) { - error_log("EST: Session not found for user=$user realm=$realm"); - die("Session not found"); - } - $row = $q->fetch(); - if (!$row) { - error_log("EST: Session fetch failed for user=$user realm=$realm"); - die('Session not found'); - } - $rowid = $row['rowid']; - - $oper = $row['operation']; - if ($oper != '10') { - error_log("EST: Unexpected operation $oper for user=$user realm=$realm"); - die("Session not found"); - } -} - - -if ($method == "GET" && $cmd == "cacerts") { - $fname = "$osu_root/est/$realm-cacerts.pkcs7"; - if (!file_exists($fname)) { - error_log("EST: cacerts - unknown realm $realm"); - die("Unknown realm"); - } - - header("Content-Transfer-Encoding: base64"); - header("Content-Type: application/pkcs7-mime"); - - $data = file_get_contents($fname); - echo wordwrap(base64_encode($data), 72, "\n", true); - echo "\n"; - error_log("EST: cacerts"); -} else if ($method == "GET" && $cmd == "csrattrs") { - header("Content-Transfer-Encoding: base64"); - header("Content-Type: application/csrattrs"); - readfile("$osu_root/est/est-attrs.b64"); - error_log("EST: csrattrs"); -} else if ($method == "POST" && - ($cmd == "simpleenroll" || $cmd == "simplereenroll")) { - $reenroll = $cmd == "simplereenroll"; - if (!$reenroll && (!isset($user) || strlen($user) == 0)) { - header('HTTP/1.1 401 Unauthorized'); - header('WWW-Authenticate: Digest realm="'.$realm. - '",qop="auth",nonce="'.uniqid().'",opaque="'.md5($realm).'"'); - error_log("EST: simpleenroll - require authentication"); - die('Authentication required'); - } - if ($reenroll && - (!isset($user) || - !isset($_SERVER["SSL_CLIENT_VERIFY"]) || - $_SERVER["SSL_CLIENT_VERIFY"] != "SUCCESS")) { - header('HTTP/1.1 403 Forbidden'); - error_log("EST: simplereenroll - require certificate authentication"); - die('Authentication required'); - } - if (!isset($_SERVER["CONTENT_TYPE"])) { - error_log("EST: simpleenroll without Content-Type"); - die("Missing Content-Type"); - } - if (!stristr($_SERVER["CONTENT_TYPE"], "application/pkcs10")) { - error_log("EST: simpleenroll - unexpected Content-Type: " . - $_SERVER["CONTENT_TYPE"]); - die("Unexpected Content-Type"); - } - - $data = file_get_contents("php://input"); - error_log("EST: simpleenroll - POST data from php://input: " . $data); - $req = base64_decode($data); - if ($req == FALSE) { - error_log("EST: simpleenroll - Invalid base64-encoded PKCS#10 data"); - die("Invalid base64-encoded PKCS#10 data"); - } - $cadir = "$osu_root/est"; - $reqfile = "$cadir/tmp/cert-req.pkcs10"; - $f = fopen($reqfile, "wb"); - fwrite($f, $req); - fclose($f); - - $req_pem = "$reqfile.pem"; - if (file_exists($req_pem)) - unlink($req_pem); - exec("openssl req -in $reqfile -inform DER -out $req_pem -outform PEM"); - if (!file_exists($req_pem)) { - error_log("EST: simpleenroll - Failed to parse certificate request"); - die("Failed to parse certificate request"); - } - - /* FIX: validate request and add HS 2.0 extensions to cert */ - $cert_pem = "$cadir/tmp/req-signed.pem"; - if (file_exists($cert_pem)) - unlink($cert_pem); - exec("openssl x509 -req -in $req_pem -CAkey $cadir/cakey.pem -out $cert_pem -CA $cadir/cacert.pem -CAserial $cadir/serial -days 365 -text"); - if (!file_exists($cert_pem)) { - error_log("EST: simpleenroll - Failed to sign certificate"); - die("Failed to sign certificate"); - } - - $cert = file_get_contents($cert_pem); - $handle = popen("openssl x509 -in $cert_pem -serial -noout", "r"); - $serial = fread($handle, 200); - pclose($handle); - $pattern = "/serial=(?P<snhex>[0-9a-fA-F:]*)/m"; - preg_match($pattern, $serial, $matches); - if (!isset($matches['snhex']) || strlen($matches['snhex']) < 1) { - error_log("EST: simpleenroll - Could not get serial number"); - die("Could not get serial number"); - } - $sn = str_replace(":", "", strtoupper($matches['snhex'])); - - $user = "cert-$sn"; - error_log("EST: user = $user"); - - $cert_der = "$cadir/tmp/req-signed.der"; - if (file_exists($cert_der)) - unlink($cert_der); - exec("openssl x509 -in $cert_pem -inform PEM -out $cert_der -outform DER"); - if (!file_exists($cert_der)) { - error_log("EST: simpleenroll - Failed to convert certificate"); - die("Failed to convert certificate"); - } - $der = file_get_contents($cert_der); - $fingerprint = hash("sha256", $der); - error_log("EST: sha256(DER cert): $fingerprint"); - - $pkcs7 = "$cadir/tmp/est-client.pkcs7"; - if (file_exists($pkcs7)) - unlink($pkcs7); - exec("openssl crl2pkcs7 -nocrl -certfile $cert_pem -out $pkcs7 -outform DER"); - if (!file_exists($pkcs7)) { - error_log("EST: simpleenroll - Failed to prepare PKCS#7 file"); - die("Failed to prepare PKCS#7 file"); - } - - if (!$db->exec("UPDATE sessions SET user='$user', cert='$fingerprint', cert_pem='$cert' WHERE rowid=$rowid")) { - error_log("EST: simpleenroll - Failed to update session database"); - die("Failed to update session database"); - } - - header("Content-Transfer-Encoding: base64"); - header("Content-Type: application/pkcs7-mime"); - - $data = file_get_contents($pkcs7); - $resp = wordwrap(base64_encode($data), 72, "\n", true); - echo $resp . "\n"; - error_log("EST: simpleenroll - PKCS#7 response: " . $resp); -} else { - header("HTTP/1.0 404 Not Found"); - error_log("EST: Unexpected method or path"); - die("Unexpected method or path"); -} - -?> diff --git a/hs20/server/www/free-remediation.php b/hs20/server/www/free-remediation.php deleted file mode 100644 index 5648b30e8d6b..000000000000 --- a/hs20/server/www/free-remediation.php +++ /dev/null @@ -1,19 +0,0 @@ -<html> -<head> -<title>Hotspot 2.0 - public and free hotspot - remediation</title> -</head> -<body> - -<h3>Hotspot 2.0 - public and free hotspot</h3> - -<p>Terms and conditions have changed. You need to accept the new terms -to continue using this network.</p> - -<p>Terms and conditions..</p> - -<?php -echo "<a href=\"redirect.php?id=" . $_GET["session_id"] . "\">Accept</a><br>\n"; -?> - -</body> -</html> diff --git a/hs20/server/www/free.php b/hs20/server/www/free.php deleted file mode 100644 index 8195069ed8ff..000000000000 --- a/hs20/server/www/free.php +++ /dev/null @@ -1,23 +0,0 @@ -<html> -<head> -<title>Hotspot 2.0 - public and free hotspot</title> -</head> -<body> - -<?php - -$id = $_GET["session_id"]; - -echo "<h3>Hotspot 2.0 - public and free hotspot</h3>\n"; - -echo "<form action=\"add-free.php\" method=\"POST\">\n"; -echo "<input type=\"hidden\" name=\"id\" value=\"$id\">\n"; - -?> - -<p>Terms and conditions..</p> -<input type="submit" value="Accept"> -</form> - -</body> -</html> diff --git a/hs20/server/www/redirect.php b/hs20/server/www/redirect.php deleted file mode 100644 index 8fc9cd644273..000000000000 --- a/hs20/server/www/redirect.php +++ /dev/null @@ -1,32 +0,0 @@ -<?php - -require('config.php'); - -$db = new PDO($osu_db); -if (!$db) { - die($sqliteerror); -} - -if (isset($_GET["id"])) - $id = preg_replace("/[^a-fA-F0-9]/", "", $_GET["id"]); -else - $id = 0; - -$row = $db->query("SELECT rowid,* FROM sessions WHERE id='$id'")->fetch(); -if ($row == false) { - die("Session not found"); -} - -$uri = $row['redirect_uri']; - -header("Location: $uri", true, 302); - -$user = $row['user']; -$realm = $row['realm']; - -$db->exec("INSERT INTO eventlog(user,realm,sessionid,timestamp,notes) " . - "VALUES ('$user', '$realm', '$id', " . - "strftime('%Y-%m-%d %H:%M:%f','now'), " . - "'redirected after user input')"); - -?> diff --git a/hs20/server/www/remediation-pw.php b/hs20/server/www/remediation-pw.php deleted file mode 100644 index 76fdccbdf9f7..000000000000 --- a/hs20/server/www/remediation-pw.php +++ /dev/null @@ -1,41 +0,0 @@ -<?php - -require('config.php'); - -$db = new PDO($osu_db); -if (!$db) { - die($sqliteerror); -} - -if (isset($_POST["id"])) - $id = preg_replace("/[^a-fA-F0-9]/", "", $_POST["id"]); -else - die("Missing session id"); - -$pw = $_POST["password"]; -if (strlen($id) < 32 || !isset($pw)) { - die("Invalid POST data"); -} - -$row = $db->query("SELECT rowid,* FROM sessions WHERE id='$id'")->fetch(); -if ($row == false) { - die("Session not found"); -} -$user = $row['user']; -$realm = $row['realm']; - -$uri = $row['redirect_uri']; -$rowid = $row['rowid']; - -if (!$db->exec("UPDATE sessions SET password='$pw' 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 subscription remediation')"); - -header("Location: $uri", true, 302); - -?> diff --git a/hs20/server/www/remediation.php b/hs20/server/www/remediation.php deleted file mode 100644 index 3628065ac225..000000000000 --- a/hs20/server/www/remediation.php +++ /dev/null @@ -1,55 +0,0 @@ -<html> -<head> -<title>Hotspot 2.0 subscription remediation</title> -</head> -<body> - -<?php - -require('config.php'); - -$db = new PDO($osu_db); -if (!$db) { - die($sqliteerror); -} - -if (isset($_GET["session_id"])) - $id = preg_replace("/[^a-fA-F0-9]/", "", $_GET["session_id"]); -else - $id = 0; -echo "SessionID: " . $id . "<br>\n"; - -$row = $db->query("SELECT * FROM sessions WHERE id='$id'")->fetch(); -if ($row == false) { - die("Session not found"); -} - -$username = $row['user']; -echo "User: " . $username . "@" . $row['realm'] . "<br>\n"; - -$user = $db->query("SELECT machine_managed,methods FROM users WHERE identity='$username'")->fetch(); -if ($user == false) { - die("User not found"); -} - -echo "<hr><br>\n"; - -$cert = $user['methods'] == "TLS" || strncmp($username, "cert-", 5) == 0; - -if ($cert) { - echo "<a href=\"redirect.php?id=" . $_GET["session_id"] . "\">Complete user subscription remediation</a><br>\n"; -} else if ($user['machine_managed'] == "1") { - echo "<a href=\"redirect.php?id=" . $_GET["session_id"] . "\">Complete user subscription remediation</a><br>\n"; - echo "This will provide a new machine-generated password.<br>\n"; -} else { - echo "<form action=\"remediation-pw.php\" method=\"POST\">\n"; - echo "<input type=\"hidden\" name=\"id\" value=\"$id\">\n"; - echo "New password: <input type=\"password\" name=\"password\"><br>\n"; - echo "<input type=\"submit\" value=\"Change password\">\n"; - echo "</form>\n"; -} - -?> - -</body> -</html> diff --git a/hs20/server/www/signup.php b/hs20/server/www/signup.php deleted file mode 100644 index 80a9d403e8fc..000000000000 --- a/hs20/server/www/signup.php +++ /dev/null @@ -1,59 +0,0 @@ -<html> -<head> -<title>Hotspot 2.0 signup</title> -</head> -<body> - -<?php - -$id = $_GET["session_id"]; - -require('config.php'); - -$db = new PDO($osu_db); -if (!$db) { - die($sqliteerror); -} - -$row = $db->query("SELECT realm,test FROM sessions WHERE id='$id'")->fetch(); -if ($row == false) { - die("Session not found for id: $id"); -} -$realm = $row['realm']; -$test = $row['test']; - -if (strlen($test) > 0) { - echo "<p style=\"color:#FF0000\">Special test functionality: $test</red></big></p>\n"; -} - -echo "<h3>Sign up for a subscription - $realm</h3>\n"; - -echo "<p>This page can be used to select between three different types of subscriptions for testing purposes.</p>\n"; - -echo "<h4>Option 1 - shared free access credential</h4>\n"; - -$row = $db->query("SELECT value FROM osu_config WHERE realm='$realm' AND field='free_account'")->fetch(); -if ($row && strlen($row['value']) > 0) { - echo "<p><a href=\"free.php?session_id=$id\">Sign up for free access</a></p>\n"; -} - -echo "<h4>Option 2 - username/password credential</h4>\n"; - -echo "<form action=\"add-mo.php\" method=\"POST\">\n"; -echo "<input type=\"hidden\" name=\"id\" value=\"$id\">\n"; -?> -Select a username and password. Leave password empty to get automatically -generated and machine managed password.<br> -Username: <input type="text" name="user"><br> -Password: <input type="password" name="password"><br> -<input type="submit" value="Complete subscription registration"> -</form> - -<?php -echo "<h4>Option 3 - client certificate credential</h4>\n"; - -echo "<p><a href=\"cert-enroll.php?id=$id\">Enroll a client certificate</a></p>\n" -?> - -</body> -</html> diff --git a/hs20/server/www/spp.php b/hs20/server/www/spp.php deleted file mode 100644 index c56d3d69e0ed..000000000000 --- a/hs20/server/www/spp.php +++ /dev/null @@ -1,168 +0,0 @@ -<?php - -require('config.php'); - -if (!stristr($_SERVER["CONTENT_TYPE"], "application/soap+xml")) { - error_log("spp.php - Unexpected Content-Type " . $_SERVER["CONTENT_TYPE"]); - die("Unexpected Content-Type"); -} - -if ($_SERVER["REQUEST_METHOD"] != "POST") { - error_log("spp.php - Unexpected method " . $_SERVER["REQUEST_METHOD"]); - die("Unexpected method"); -} - -if (isset($_GET["realm"])) { - $realm = $_GET["realm"]; - $realm = PREG_REPLACE("/[^0-9a-zA-Z\.\-]/i", '', $realm); -} else { - error_log("spp.php - Realm not specified"); - die("Realm not specified"); -} - -if (isset($_GET["test"])) - $test = PREG_REPLACE("/[^0-9a-zA-Z\_\-]/i", '', $_GET["test"]); -else - $test = ""; - -unset($user); -putenv("HS20CERT"); - -if (!empty($_SERVER['PHP_AUTH_DIGEST'])) { - $needed = array('nonce'=>1, 'nc'=>1, 'cnonce'=>1, 'qop'=>1, 'username'=>1, - 'uri'=>1, 'response'=>1); - $data = array(); - $keys = implode('|', array_keys($needed)); - preg_match_all('@(' . $keys . ')=(?:([\'"])([^\2]+?)\2|([^\s,]+))@', - $_SERVER['PHP_AUTH_DIGEST'], $matches, PREG_SET_ORDER); - foreach ($matches as $m) { - $data[$m[1]] = $m[3] ? $m[3] : $m[4]; - unset($needed[$m[1]]); - } - if ($needed) { - error_log("spp.php - Authentication failed - missing: " . print_r($needed)); - die('Authentication failed'); - } - $user = $data['username']; - if (strlen($user) < 1) { - error_log("spp.php - Authentication failed - empty username"); - die('Authentication failed'); - } - - - $db = new PDO($osu_db); - if (!$db) { - error_log("spp.php - Could not access database"); - die("Could not access database"); - } - $row = $db->query("SELECT password FROM users " . - "WHERE identity='$user' AND realm='$realm'")->fetch(); - if (!$row) { - $row = $db->query("SELECT osu_password FROM users " . - "WHERE osu_user='$user' AND realm='$realm'")->fetch(); - $pw = $row['osu_password']; - } else - $pw = $row['password']; - if (!$row) { - error_log("spp.php - Authentication failed - user '$user' not found"); - die('Authentication failed'); - } - if (strlen($pw) < 1) { - error_log("spp.php - Authentication failed - empty password"); - die('Authentication failed'); - } - - $A1 = md5($user . ':' . $realm . ':' . $pw); - $A2 = md5($_SERVER['REQUEST_METHOD'] . ':' . $data['uri']); - $resp = md5($A1 . ':' . $data['nonce'] . ':' . $data['nc'] . ':' . - $data['cnonce'] . ':' . $data['qop'] . ':' . $A2); - if ($data['response'] != $resp) { - error_log("Authentication failure - response mismatch"); - die('Authentication failed'); - } -} else if (isset($_SERVER["SSL_CLIENT_VERIFY"]) && - $_SERVER["SSL_CLIENT_VERIFY"] == "SUCCESS" && - isset($_SERVER["SSL_CLIENT_M_SERIAL"])) { - $user = "cert-" . $_SERVER["SSL_CLIENT_M_SERIAL"]; - putenv("HS20CERT=yes"); -} else if (isset($_GET["hotspot2dot0-mobile-identifier-hash"])) { - $id_hash = $_GET["hotspot2dot0-mobile-identifier-hash"]; - $id_hash = PREG_REPLACE("/[^0-9a-h]/i", '', $id_hash); - - $db = new PDO($osu_db); - if (!$db) { - error_log("spp.php - Could not access database"); - die("Could not access database"); - } - - $row = $db->query("SELECT * FROM sim_provisioning " . - "WHERE mobile_identifier_hash='$id_hash'")->fetch(); - if (!$row) { - error_log("spp.php - SIM provisioning failed - mobile_identifier_hash not found"); - die('SIM provisioning failed - mobile_identifier_hash not found'); - } - - $imsi = $row['imsi']; - $mac_addr = $row['mac_addr']; - $eap_method = $row['eap_method']; - - $row = $db->query("SELECT COUNT(*) FROM osu_config " . - "WHERE realm='$realm'")->fetch(); - if (!$row || intval($row[0]) < 1) { - error_log("spp.php - SIM provisioning failed - realm $realm not found"); - die('SIM provisioning failed'); - } - - error_log("spp.php - SIM provisioning for IMSI $imsi"); - putenv("HS20SIMPROV=yes"); - putenv("HS20IMSI=$imsi"); - putenv("HS20MACADDR=$mac_addr"); - putenv("HS20EAPMETHOD=$eap_method"); - putenv("HS20IDHASH=$id_hash"); -} else if (!isset($_SERVER["PATH_INFO"]) || - $_SERVER["PATH_INFO"] != "/signup") { - header('HTTP/1.1 401 Unauthorized'); - header('WWW-Authenticate: Digest realm="'.$realm. - '",qop="auth",nonce="'.uniqid().'",opaque="'.md5($realm).'"'); - error_log("spp.php - Authentication required (not signup)"); - die('Authentication required (not signup)'); -} - - -if (isset($user) && strlen($user) > 0) - putenv("HS20USER=$user"); -else - putenv("HS20USER"); - -putenv("HS20REALM=$realm"); -$postdata = file_get_contents("php://input"); -putenv("HS20POST=$postdata"); -$addr = $_SERVER["REMOTE_ADDR"]; -putenv("HS20ADDR=$addr"); -putenv("HS20TEST=$test"); - -$last = exec("$osu_root/spp/hs20_spp_server -r$osu_root -f/tmp/hs20_spp_server.log", $output, $ret); - -if ($ret == 2) { - if (empty($_SERVER['PHP_AUTH_DIGEST'])) { - header('HTTP/1.1 401 Unauthorized'); - header('WWW-Authenticate: Digest realm="'.$realm. - '",qop="auth",nonce="'.uniqid().'",opaque="'.md5($realm).'"'); - error_log("spp.php - Authentication required (ret 2)"); - die('Authentication required'); - } else { - error_log("spp.php - Unexpected authentication error"); - die("Unexpected authentication error"); - } -} -if ($ret != 0) { - error_log("spp.php - Failed to process SPP request"); - die("Failed to process SPP request"); -} -//error_log("spp.php: Response: " . implode($output)); - -header("Content-Type: application/soap+xml"); - -echo implode($output); - -?> diff --git a/hs20/server/www/terms.php b/hs20/server/www/terms.php deleted file mode 100644 index acba23ef1ad7..000000000000 --- a/hs20/server/www/terms.php +++ /dev/null @@ -1,87 +0,0 @@ -<?php - -require('config.php'); - -function print_header() -{ - echo "<html>\n"; - echo "<head><title>HS 2.0 Terms and Conditions</title></head>\n"; - echo "<body>\n"; -} - -$db = new PDO($osu_db); -if (!$db) { - die($sqliteerror); -} - -if (!isset($_GET["addr"])) { - die("Missing addr parameter"); -} -$addr = $_GET["addr"]; - -$accept = isset($_GET["accept"]) && $_GET["accept"] == "yes"; - -$res = $db->prepare("SELECT identity FROM pending_tc WHERE mac_addr=?"); -$res->execute(array($addr)); -$row = $res->fetch(); -if (!$row) { - die("No pending session for the specified MAC address"); -} -$identity = $row[0]; - -if (!$accept) { - print_header(); - - echo "<p>Accept the following terms and conditions by clicking here: <a href=\"terms.php?addr=$addr&accept=yes\">Accept</a></p>\n<hr>\n"; - readfile($t_c_file); -} else { - $res = $db->prepare("UPDATE users SET t_c_timestamp=? WHERE identity=?"); - if (!$res->execute(array($t_c_timestamp, $identity))) { - die("Failed to update user account."); - } - - $res = $db->prepare("DELETE FROM pending_tc WHERE mac_addr=?"); - $res->execute(array($addr)); - - $fp = fsockopen($hostapd_ctrl); - if (!$fp) { - die("Could not connect to hostapd(AS)"); - } - - fwrite($fp, "DAC_REQUEST coa $addr t_c_clear"); - fclose($fp); - - $waiting = true; - $ack = false; - for ($i = 1; $i <= 10; $i++) { - $res = $db->prepare("SELECT waiting_coa_ack,coa_ack_received FROM current_sessions WHERE mac_addr=?"); - $res->execute(array($addr)); - $row = $res->fetch(); - if (!$row) { - die("No current session for the specified MAC address"); - } - if (strlen($row[0]) > 0) - $waiting = $row[0] == 1; - if (strlen($row[1]) > 0) - $ack = $row[1] == 1; - $res->closeCursor(); - if (!$waiting) - break; - sleep(1); - } - if ($ack) { - header('X-WFA-Hotspot20-Filtering: removed'); - print_header(); - echo "<p>Terms and conditions were accepted.</p>\n"; - - echo "<P>Filtering disabled.</P>\n"; - } else { - print_header(); - echo "<P>Failed to disable filtering.</P>\n"; - } -} - -?> - -</body> -</html> diff --git a/hs20/server/www/users.php b/hs20/server/www/users.php deleted file mode 100644 index 2bd555275dda..000000000000 --- a/hs20/server/www/users.php +++ /dev/null @@ -1,377 +0,0 @@ -<?php - -require('config.php'); - -$db = new PDO($osu_db); -if (!$db) { - die($sqliteerror); -} - -if (isset($_GET["id"])) { - $id = $_GET["id"]; - if (!is_numeric($id)) - $id = 0; -} else - $id = 0; -if (isset($_GET["cmd"])) - $cmd = $_GET["cmd"]; -else - $cmd = ''; - -if ($cmd == 'eventlog' && $id > 0) { - $row = $db->query("SELECT dump FROM eventlog WHERE rowid=$id")->fetch(); - $dump = $row['dump']; - if ($dump[0] == '<') { - header("Content-type: text/xml"); - echo "<?xml version=\"1.0\"?>\n"; - echo $dump; - } else { - header("Content-type: text/plain"); - echo $dump; - } - exit; -} - -if ($cmd == 'mo' && $id > 0) { - $mo = $_GET["mo"]; - if (!isset($mo)) - exit; - if ($mo != "devinfo" && $mo != "devdetail" && $mo != "pps") - exit; - $row = $db->query("SELECT $mo FROM users WHERE rowid=$id")->fetch(); - header("Content-type: text/xml"); - echo "<?xml version=\"1.0\"?>\n"; - echo $row[$mo]; - exit; -} - -if ($cmd == 'cert' && $id > 0) { - $row = $db->query("SELECT cert_pem FROM users WHERE rowid=$id")->fetch(); - header("Content-type: text/plain"); - echo $row['cert_pem']; - exit; -} - -?> - -<html> -<head><title>HS 2.0 users</title></head> -<body> - -<?php - -if ($cmd == 'subrem-clear' && $id > 0) { - $db->exec("UPDATE users SET remediation='' WHERE rowid=$id"); -} -if ($cmd == 'subrem-add-user' && $id > 0) { - $db->exec("UPDATE users SET remediation='user' WHERE rowid=$id"); -} -if ($cmd == 'subrem-add-machine' && $id > 0) { - $db->exec("UPDATE users SET remediation='machine' WHERE rowid=$id"); -} -if ($cmd == 'subrem-add-reenroll' && $id > 0) { - $db->exec("UPDATE users SET remediation='reenroll' WHERE rowid=$id"); -} -if ($cmd == 'subrem-add-policy' && $id > 0) { - $db->exec("UPDATE users SET remediation='policy' WHERE rowid=$id"); -} -if ($cmd == 'subrem-add-free' && $id > 0) { - $db->exec("UPDATE users SET remediation='free' WHERE rowid=$id"); -} -if ($cmd == 'fetch-pps-on' && $id > 0) { - $db->exec("UPDATE users SET fetch_pps=1 WHERE rowid=$id"); -} -if ($cmd == 'fetch-pps-off' && $id > 0) { - $db->exec("UPDATE users SET fetch_pps=0 WHERE rowid=$id"); -} -if ($cmd == 'reset-pw' && $id > 0) { - $db->exec("UPDATE users SET password='ChangeMe' WHERE rowid=$id"); -} -if ($cmd == "policy" && $id > 0 && isset($_GET["policy"])) { - $policy = $_GET["policy"]; - if ($policy == "no-policy" || - is_readable("$osu_root/spp/policy/$policy.xml")) { - $db->exec("UPDATE users SET policy='$policy' WHERE rowid=$id"); - } -} -if ($cmd == "account-type" && $id > 0 && isset($_GET["type"])) { - $type = $_GET["type"]; - if ($type == "shared") - $db->exec("UPDATE users SET shared=1 WHERE rowid=$id"); - if ($type == "default") - $db->exec("UPDATE users SET shared=0 WHERE rowid=$id"); -} - -if ($cmd == "set-osu-cred" && $id > 0) { - $osu_user = $_POST["osu_user"]; - $osu_password = $_POST["osu_password"]; - if (strlen($osu_user) == 0) - $osu_password = ""; - $db->exec("UPDATE users SET osu_user='$osu_user', osu_password='$osu_password' WHERE rowid=$id"); -} - -if ($cmd == 'clear-t-c' && $id > 0) { - $db->exec("UPDATE users SET t_c_timestamp=NULL WHERE rowid=$id"); -} - -$dump = 0; - -if ($id > 0) { - -if (isset($_GET["dump"])) { - $dump = $_GET["dump"]; - if (!is_numeric($dump)) - $dump = 0; -} else - $dump = 0; - -echo "[<a href=\"users.php\">All users</a>] "; -if ($dump == 0) - echo "[<a href=\"users.php?id=$id&dump=1\">Include debug dump</a>] "; -else - echo "[<a href=\"users.php?id=$id\">Without debug dump</a>] "; -echo "<br>\n"; - -$row = $db->query("SELECT rowid,* FROM users WHERE rowid=$id")->fetch(); - -echo "<H3>" . $row['identity'] . "@" . $row['realm'] . "</H3>\n"; - -echo "MO: "; -if (strlen($row['devinfo']) > 0) { - echo "[<a href=\"users.php?cmd=mo&id=$id&mo=devinfo\">DevInfo</a>]\n"; -} -if (strlen($row['devdetail']) > 0) { - echo "[<a href=\"users.php?cmd=mo&id=$id&mo=devdetail\">DevDetail</a>]\n"; -} -if (strlen($row['pps']) > 0) { - echo "[<a href=\"users.php?cmd=mo&id=$id&mo=pps\">PPS</a>]\n"; -} -if (strlen($row['cert_pem']) > 0) { - echo "[<a href=\"users.php?cmd=cert&id=$id\">Certificate</a>]\n"; -} -echo "<BR>\n"; - -echo "Fetch PPS MO: "; -if ($row['fetch_pps'] == "1") { - echo "On next connection " . - "[<a href=\"users.php?cmd=fetch-pps-off&id=$id\">" . - "do not fetch</a>]<br>\n"; -} else { - echo "Do not fetch " . - "[<a href=\"users.php?cmd=fetch-pps-on&id=$id\">" . - "request fetch</a>]<br>\n"; -} - -$cert = $row['cert']; -if (strlen($cert) > 0) { - echo "Certificate fingerprint: $cert<br>\n"; -} - -echo "Remediation: "; -$rem = $row['remediation']; -if ($rem == "") { - echo "Not required"; - echo " [<a href=\"users.php?cmd=subrem-add-user&id=" . - $row['rowid'] . "\">add:user</a>]"; - echo " [<a href=\"users.php?cmd=subrem-add-machine&id=" . - $row['rowid'] . "\">add:machine</a>]"; - if ($row['methods'] == 'TLS') { - echo " [<a href=\"users.php?cmd=subrem-add-reenroll&id=" . - $row['rowid'] . "\">add:reenroll</a>]"; - } - echo " [<a href=\"users.php?cmd=subrem-add-policy&id=" . - $row['rowid'] . "\">add:policy</a>]"; - echo " [<a href=\"users.php?cmd=subrem-add-free&id=" . - $row['rowid'] . "\">add:free</a>]"; -} else if ($rem == "user") { - echo "User [<a href=\"users.php?cmd=subrem-clear&id=" . - $row['rowid'] . "\">clear</a>]"; -} else if ($rem == "policy") { - echo "Policy [<a href=\"users.php?cmd=subrem-clear&id=" . - $row['rowid'] . "\">clear</a>]"; -} else if ($rem == "free") { - echo "Free [<a href=\"users.php?cmd=subrem-clear&id=" . - $row['rowid'] . "\">clear</a>]"; -} else if ($rem == "reenroll") { - echo "Reenroll [<a href=\"users.php?cmd=subrem-clear&id=" . - $row['rowid'] . "\">clear</a>]"; -} else { - echo "Machine [<a href=\"users.php?cmd=subrem-clear&id=" . - $row['rowid'] . "\">clear</a>]"; -} -echo "<br>\n"; - -if (strncmp($row['identity'], "cert-", 5) != 0) - echo "Machine managed: " . ($row['machine_managed'] == "1" ? "TRUE" : "FALSE") . "<br>\n"; - -echo "<form>Policy: <select name=\"policy\" " . - "onChange=\"window.location='users.php?cmd=policy&id=" . - $row['rowid'] . "&policy=' + this.value;\">\n"; -echo "<option value=\"" . $row['policy'] . "\" selected>" . $row['policy'] . - "</option>\n"; -$files = scandir("$osu_root/spp/policy"); -foreach ($files as $file) { - if (!preg_match("/.xml$/", $file)) - continue; - if ($file == $row['policy'] . ".xml") - continue; - $p = substr($file, 0, -4); - echo "<option value=\"$p\">$p</option>\n"; -} -echo "<option value=\"no-policy\">no policy</option>\n"; -echo "</select></form>\n"; - -echo "<form>Account type: <select name=\"type\" " . - "onChange=\"window.location='users.php?cmd=account-type&id=" . - $row['rowid'] . "&type=' + this.value;\">\n"; -if ($row['shared'] > 0) { - $default_sel = ""; - $shared_sel = " selected"; -} else { - $default_sel = " selected"; - $shared_sel = ""; -} -echo "<option value=\"default\"$default_sel>default</option>\n"; -echo "<option value=\"shared\"$shared_sel>shared</option>\n"; -echo "</select></form>\n"; - -echo "Phase 2 method(s): " . $row['methods'] . "<br>\n"; - -echo "<br>\n"; -echo "<a href=\"users.php?cmd=reset-pw&id=" . - $row['rowid'] . "\">Reset AAA password</a><br>\n"; - -echo "<br>\n"; -echo "<form action=\"users.php?cmd=set-osu-cred&id=" . $row['rowid'] . - "\" method=\"POST\">\n"; -echo "OSU credentials (if username empty, AAA credentials are used):<br>\n"; -echo "username: <input type=\"text\" name=\"osu_user\" value=\"" . - $row['osu_user'] . "\">\n"; -echo "password: <input type=\"password\" name=\"osu_password\">\n"; -echo "<input type=\"submit\" value=\"Set OSU credentials\">\n"; -echo "</form>\n"; - -if (strlen($row['t_c_timestamp']) > 0) { - echo "<br>\n"; - echo "<a href=\"users.php?cmd=clear-t-c&id=" . - $row['rowid'] . - "\">Clear Terms and Conditions acceptance</a><br>\n"; -} - -echo "<hr>\n"; - -$user = $row['identity']; -$osu_user = $row['osu_user']; -$realm = $row['realm']; -} - -if ($id > 0 || ($id == 0 && $cmd == 'eventlog')) { - - if ($id == 0) { - echo "[<a href=\"users.php\">All users</a>] "; - echo "<br>\n"; - } - -echo "<table border=1>\n"; -echo "<tr>"; -if ($id == 0) { - echo "<th>user<th>realm"; -} -echo "<th>time<th>address<th>sessionID<th>notes"; -if ($dump > 0) - echo "<th>dump"; -echo "\n"; -if (isset($_GET["limit"])) { - $limit = $_GET["limit"]; - if (!is_numeric($limit)) - $limit = 20; -} else - $limit = 20; -if ($id == 0) - $res = $db->query("SELECT rowid,* FROM eventlog ORDER BY timestamp DESC LIMIT $limit"); -else if (strlen($osu_user) > 0) - $res = $db->query("SELECT rowid,* FROM eventlog WHERE (user='$user' OR user='$osu_user') AND realm='$realm' ORDER BY timestamp DESC LIMIT $limit"); -else - $res = $db->query("SELECT rowid,* FROM eventlog WHERE user='$user' AND realm='$realm' ORDER BY timestamp DESC LIMIT $limit"); -foreach ($res as $row) { - echo "<tr>"; - if ($id == 0) { - echo "<td>" . $row['user'] . "\n"; - echo "<td>" . $row['realm'] . "\n"; - } - echo "<td>" . $row['timestamp'] . "\n"; - echo "<td>" . $row['addr'] . "\n"; - echo "<td>" . $row['sessionid'] . "\n"; - echo "<td>" . $row['notes'] . "\n"; - $d = $row['dump']; - if (strlen($d) > 0) { - echo "[<a href=\"users.php?cmd=eventlog&id=" . $row['rowid'] . - "\">"; - if ($d[0] == '<') - echo "XML"; - else - echo "txt"; - echo "</a>]\n"; - if ($dump > 0) - echo "<td>" . htmlspecialchars($d) . "\n"; - } -} -echo "</table>\n"; - -} - - -if ($id == 0 && $cmd != 'eventlog') { - -echo "[<a href=\"users.php?cmd=eventlog&limit=50\">Eventlog</a>] "; -echo "<br>\n"; - -echo "<table border=1 cellspacing=0 cellpadding=0>\n"; -echo "<tr><th>User<th>Realm<th><small>Remediation</small><th>Policy<th><small>Account type</small><th><small>Phase 2 method(s)</small><th>DevId<th>MAC Address<th>T&C\n"; - -$res = $db->query('SELECT rowid,* FROM users WHERE (phase2=1 OR methods=\'TLS\') ORDER BY identity'); -foreach ($res as $row) { - echo "<tr><td><a href=\"users.php?id=" . $row['rowid'] . "\"> " . - $row['identity'] . " </a>"; - echo "<td>" . $row['realm']; - $rem = $row['remediation']; - echo "<td>"; - if ($rem == "") { - echo "-"; - } else if ($rem == "user") { - echo "User"; - } else if ($rem == "policy") { - echo "Policy"; - } else if ($rem == "free") { - echo "Free"; - } else if ($rem == "reenroll") { - echo "Reenroll"; - } else { - echo "Machine"; - } - echo "<td>" . $row['policy']; - if ($row['shared'] > 0) - echo "<td>shared"; - else - echo "<td>default"; - echo "<td><small>" . $row['methods'] . "</small>"; - echo "<td>"; - $xml = xml_parser_create(); - xml_parse_into_struct($xml, $row['devinfo'], $devinfo); - foreach($devinfo as $k) { - if ($k['tag'] == 'DEVID') { - echo "<small>" . $k['value'] . "</small>"; - break; - } - } - echo "<td><small>" . $row['mac_addr'] . "</small>"; - echo "<td><small>" . $row['t_c_timestamp'] . "</small>"; - echo "\n"; -} -echo "</table>\n"; - -} - -?> - -</html> |