xref: /OpenGrok/plugins/src/test/java/opengrok/auth/plugin/configuration/ConfigurationTest.java (revision 14bb522c9f0e0c2ecef1a684c4dfe9ab698ba53c)
1 /*
2  * CDDL HEADER START
3  *
4  * The contents of this file are subject to the terms of the
5  * Common Development and Distribution License (the "License").
6  * You may not use this file except in compliance with the License.
7  *
8  * See LICENSE.txt included in this distribution for the specific
9  * language governing permissions and limitations under the License.
10  *
11  * When distributing Covered Code, include this CDDL HEADER in each
12  * file and include the License file at LICENSE.txt.
13  * If applicable, add the following below this CDDL HEADER, with the
14  * fields enclosed by brackets "[]" replaced with your own identifying
15  * information: Portions Copyright [yyyy] [name of copyright owner]
16  *
17  * CDDL HEADER END
18  */
19 
20 /*
21  * Copyright (c) 2016, 2021, Oracle and/or its affiliates. All rights reserved.
22  */
23 package opengrok.auth.plugin.configuration;
24 
25 import java.beans.ExceptionListener;
26 import java.beans.XMLDecoder;
27 import java.beans.XMLEncoder;
28 import java.io.ByteArrayInputStream;
29 import java.io.ByteArrayOutputStream;
30 import java.io.File;
31 import java.io.IOException;
32 import java.util.ArrayList;
33 import java.util.LinkedList;
34 import java.util.List;
35 
36 import opengrok.auth.plugin.ldap.LdapServer;
37 import opengrok.auth.plugin.util.WebHook;
38 import opengrok.auth.plugin.util.WebHooks;
39 import org.junit.jupiter.api.Test;
40 import org.junit.jupiter.params.ParameterizedTest;
41 import org.junit.jupiter.params.provider.ValueSource;
42 
43 import static org.junit.jupiter.api.Assertions.assertEquals;
44 import static org.junit.jupiter.api.Assertions.assertNotNull;
45 import static org.junit.jupiter.api.Assertions.assertThrows;
46 
47 /**
48  *
49  * @author Krystof Tulinger
50  */
51 class ConfigurationTest {
52 
53     @Test
testEncodeDecode()54     void testEncodeDecode() {
55         // Create an exception listener to detect errors while encoding and
56         // decoding
57         final LinkedList<Exception> exceptions = new LinkedList<>();
58         ExceptionListener listener = exceptions::addLast;
59 
60         ByteArrayOutputStream out = new ByteArrayOutputStream();
61         XMLEncoder enc = new XMLEncoder(out);
62         enc.setExceptionListener(listener);
63 
64         Configuration configuration1 = new Configuration();
65         configuration1.setInterval(500);
66         configuration1.setSearchTimeout(1000);
67         configuration1.setConnectTimeout(42);
68         configuration1.setCountLimit(10);
69         configuration1.setServers(new ArrayList<>(List.of(new LdapServer("http://server.com"))));
70         WebHooks webHooks = new WebHooks();
71         WebHook hook = new WebHook();
72         hook.setContent("foo");
73         hook.setURI("http://localhost:8080/source/api/v1/messages");
74         webHooks.setFail(hook);
75         configuration1.setWebHooks(webHooks);
76 
77         enc.writeObject(configuration1);
78         enc.close();
79 
80         // verify that the write didn't fail
81         if (!exceptions.isEmpty()) {
82             throw new AssertionError( "Got " + exceptions.size() + " exception(s)", exceptions.getFirst());
83         }
84 
85         ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray());
86         XMLDecoder dec = new XMLDecoder(in, null, listener);
87         Configuration configuration2 = (Configuration) dec.readObject();
88         assertNotNull(configuration2);
89         assertEquals(configuration1.getXMLRepresentationAsString(),
90                 configuration2.getXMLRepresentationAsString());
91 
92         dec.close();
93         // verify that the read didn't fail
94         if (!exceptions.isEmpty()) {
95             throw new AssertionError( "Got " + exceptions.size() + " exception(s)", exceptions.getFirst());
96         }
97     }
98 
99     @ParameterizedTest
100     @ValueSource(strings = {
101             "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" +
102                     "<java version=\"11.0.8\" class=\"java.beans.XMLDecoder\">\n" +
103                     "  <object class=\"java.lang.Runtime\" method=\"getRuntime\">\n" +
104                     "    <void method=\"exec\">\n" +
105                     "      <array class=\"java.lang.String\" length=\"2\">\n" +
106                     "        <void index=\"0\">\n" +
107                     "          <string>/usr/bin/nc</string>\n" +
108                     "        </void>\n" +
109                     "        <void index=\"1\">\n" +
110                     "          <string>-l</string>\n" +
111                     "        </void>\n" +
112                     "      </array>\n" +
113                     "    </void>\n" +
114                     "  </object>\n" +
115                     "</java>",
116             "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" +
117                     "<java version=\"11.0.8\" class=\"java.beans.XMLDecoder\">\n" +
118                     "  <object class=\"java.lang.ProcessBuilder\">\n" +
119                     "    <array class=\"java.lang.String\" length=\"1\" >\n" +
120                     "      <void index=\"0\"> \n" +
121                     "        <string>/usr/bin/curl https://oracle.com</string>\n" +
122                     "      </void>\n" +
123                     "    </array>\n" +
124                     "    <void method=\"start\"/>\n" +
125                     "  </object>\n" +
126                     "</java>",
127             "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" +
128                     "<java version=\"11.0.8\" class=\"java.beans.XMLDecoder\">\n" +
129                     "  <object class = \"java.io.FileOutputStream\"> \n" +
130                     "    <string>opengrok_test.txt</string>\n" +
131                     "    <method name = \"write\">\n" +
132                     "      <array class=\"byte\" length=\"3\">\n" +
133                     "        <void index=\"0\"><byte>96</byte></void>\n" +
134                     "        <void index=\"1\"><byte>96</byte></void>\n" +
135                     "        <void index=\"2\"><byte>96</byte></void>\n" +
136                     "      </array>\n" +
137                     "    </method>\n" +
138                     "    <method name=\"close\"/>\n" +
139                     "  </object>\n" +
140                     "</java>"
141     })
testDeserializationOfNotWhiteListedClassThrowsError(final String exploit)142     void testDeserializationOfNotWhiteListedClassThrowsError(final String exploit) {
143         assertThrows(IllegalAccessError.class, () -> Configuration.makeXMLStringAsConfiguration(exploit));
144     }
145 
146     @Test
testReadCacheValid()147     void testReadCacheValid() throws IOException {
148         File testFile = new File(ConfigurationTest.class.getClassLoader().
149                 getResource("opengrok/auth/plugin/configuration/plugin-config.xml").getFile());
150         Configuration config = Configuration.read(testFile);
151         assertNotNull(config);
152         assertEquals(2, config.getServers().size());
153     }
154 }
155