1<?php
2
3/**
4 * ADFS SAML authentication plugin
5 *
6 * @author     Andreas Gohr <gohr@cosmocode.de>
7 */
8class admin_plugin_adfs extends DokuWiki_Admin_Plugin
9{
10    protected $xml = '';
11
12    public function handle()
13    {
14        global $INPUT;
15        if ($INPUT->str('url')) {
16            $http = new DokuHTTPClient();
17            $xml = $http->get($INPUT->str('url'));
18            if ($xml === false) {
19                msg('Failed to download metadata. ' . hsc($http->error), -1);
20            } else {
21                $this->xml = $xml;
22            }
23        } elseif ($INPUT->has('xml')) {
24            header("X-XSS-Protection: 0");
25            $this->xml = $INPUT->str('xml');
26        }
27
28    }
29
30    public function html()
31    {
32        echo $this->locale_xhtml('intro');
33
34        $form = new \dokuwiki\Form\Form();
35        $form->addFieldsetOpen('Federation Metadata');
36        $urlinput = $form->addTextInput('url', 'Metadata Endpoint');
37        if ($this->xml) $urlinput->val('')->useInput(false);
38        $form->addTextarea('xml', 'The XML Metadata')->val($this->xml)->useInput(false);
39        $form->addButton('go', 'Submit')->attr('type', 'submit');
40        $form->addFieldsetClose();
41        echo $form->toHTML();
42
43        if ($this->xml) {
44            $data = $this->metaData($this->xml);
45            if (count($data)) {
46                echo $this->locale_xhtml('found');
47
48                echo '<dl>';
49                foreach ($data as $key => $val) {
50                    echo '<dt>' . hsc($key) . '</dt>';
51                    echo '<dd><code>' . hsc($val) . '</code></dd>';
52                }
53                echo '</dl>';
54            } else {
55                echo $this->locale_xhtml('notfound');
56            }
57        }
58    }
59
60    /**
61     * Parse the metadata and return the configuration values
62     */
63    public function metaData($xml)
64    {
65
66        $xml = @simplexml_load_string($xml);
67        if ($xml === false) {
68            msg('Failed to parse the the XML', -1);
69            return [];
70        }
71
72        $xml->registerXPathNamespace('md', 'urn:oasis:names:tc:SAML:2.0:metadata');
73        $xml->registerXPathNamespace('ds', 'http://www.w3.org/2000/09/xmldsig#');
74
75        $proto = '/md:EntityDescriptor/md:IDPSSODescriptor[@protocolSupportEnumeration="urn:oasis:names:tc:SAML:2.0:protocol"]';
76        $data['idPEntityID'] = (string)$xml['entityID'];
77        $data['endpoint'] = (string)($xml->xpath($proto . '/md:SingleSignOnService[@Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect"]'))[0]['Location'];
78        $data['certificate'] = (string)($xml->xpath($proto . '/md:KeyDescriptor[@use="signing"]/ds:KeyInfo/ds:X509Data/ds:X509Certificate'))[0];
79
80        return $data;
81    }
82
83
84}
85