1<%@ page contentType="text/html; charset=UTF-8" %>
2<%@ page import="java.time.Duration" %>
3<%@ page import="java.util.HashMap" %>
4<%@ page import="java.util.Map" %>
5<%@ page import="org.jivesoftware.openfire.XMPPServer" %>
6<%@ page import="org.jivesoftware.openfire.session.ConnectionSettings" %>
7<%@ page import="org.jivesoftware.openfire.spi.ConnectionConfiguration" %>
8<%@ page import="org.jivesoftware.openfire.spi.ConnectionListener" %>
9<%@ page import="org.jivesoftware.openfire.spi.ConnectionManagerImpl" %>
10<%@ page import="org.jivesoftware.openfire.spi.ConnectionType" %>
11<%@ page import="org.jivesoftware.util.CookieUtils" %>
12<%@ page import="org.jivesoftware.util.JiveGlobals" %>
13<%@ page import="org.jivesoftware.util.ParamUtils" %>
14<%@ page import="org.jivesoftware.util.StringUtils" %>
15<%@ page errorPage="error.jsp" %>
16
17<%@ taglib uri="admin" prefix="admin" %>
18<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
19<%@ taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix="fmt" %>
20<jsp:useBean id="webManager" class="org.jivesoftware.util.WebManager"  />
21<% webManager.init(request, response, session, application, out ); %>
22<%
23    final ConnectionType connectionType = ConnectionType.SOCKET_C2S;
24    final ConnectionManagerImpl manager = (ConnectionManagerImpl) XMPPServer.getInstance().getConnectionManager();
25
26    final ConnectionConfiguration plaintextConfiguration  = manager.getListener( connectionType, false ).generateConnectionConfiguration();
27    final ConnectionConfiguration legacymodeConfiguration = manager.getListener( connectionType, true  ).generateConnectionConfiguration();
28
29    boolean update = request.getParameter( "update" ) != null;
30    final Map<String, String> errors = new HashMap<>();
31    Cookie csrfCookie = CookieUtils.getCookie(request, "csrf");
32    String csrfParam = ParamUtils.getParameter(request, "csrf");
33
34    if (update) {
35        if (csrfCookie == null || csrfParam == null || !csrfCookie.getValue().equals(csrfParam)) {
36            update = false;
37            errors.put("csrf", "CSRF Failure!");
38        }
39    }
40    csrfParam = StringUtils.randomString(15);
41    CookieUtils.setCookie(request, response, "csrf", csrfParam, -1);
42    pageContext.setAttribute("csrf", csrfParam);
43
44    if ( update && errors.isEmpty() )
45    {
46        // plaintext
47        final boolean plaintextEnabled      = ParamUtils.getBooleanParameter( request, "plaintext-enabled" );
48        final int plaintextTcpPort          = ParamUtils.getIntParameter( request, "plaintext-tcpPort", plaintextConfiguration.getPort() );
49
50        // legacymode
51        final boolean legacymodeEnabled      = ParamUtils.getBooleanParameter( request, "legacymode-enabled" );
52        final int legacymodeTcpPort          = ParamUtils.getIntParameter( request, "legacymode-tcpPort", legacymodeConfiguration.getPort() );
53
54        // Apply
55        final ConnectionListener plaintextListener  = manager.getListener( connectionType, false );
56        final ConnectionListener legacymodeListener = manager.getListener( connectionType, true  );
57
58        plaintextListener.enable( plaintextEnabled );
59        plaintextListener.setPort( plaintextTcpPort );
60
61        legacymodeListener.enable( legacymodeEnabled );
62        legacymodeListener.setPort( legacymodeTcpPort );
63
64        // Log the event
65        webManager.logEvent( "Updated connection settings for " + connectionType, "plain: enabled=" + plaintextEnabled + ", port=" + plaintextTcpPort + "\nlegacy: enabled=" + legacymodeEnabled+ ", port=" + legacymodeTcpPort+ "\n" );
66        response.sendRedirect( "connection-settings-socket-c2s.jsp?success=true" );
67
68
69        // TODO below is the 'idle connection' handing. This should go into the connection configuration, like all other configuration.
70        final int clientIdle = 1000* ParamUtils.getIntParameter(request, "clientIdle", -1);
71        final boolean idleDisco = ParamUtils.getBooleanParameter(request, "idleDisco");
72        final boolean pingIdleClients = ParamUtils.getBooleanParameter(request, "pingIdleClients");
73
74        if (!idleDisco) {
75            ConnectionSettings.Client.IDLE_TIMEOUT_PROPERTY.setValue(Duration.ofMillis(-1));
76        } else {
77            ConnectionSettings.Client.IDLE_TIMEOUT_PROPERTY.setValue(Duration.ofMillis(clientIdle));
78        }
79        ConnectionSettings.Client.KEEP_ALIVE_PING_PROPERTY.setValue(pingIdleClients);
80
81        webManager.logEvent("set server property " + ConnectionSettings.Client.IDLE_TIMEOUT_PROPERTY.getKey(), ConnectionSettings.Client.IDLE_TIMEOUT_PROPERTY.getKey() + " = " + ConnectionSettings.Client.IDLE_TIMEOUT_PROPERTY.getDisplayValue());
82        webManager.logEvent("set server property " + ConnectionSettings.Client.KEEP_ALIVE_PING_PROPERTY.getKey(), ConnectionSettings.Client.KEEP_ALIVE_PING_PROPERTY.getKey() + " = " + ConnectionSettings.Client.KEEP_ALIVE_PING_PROPERTY.getDisplayValue());
83
84        return;
85    }
86
87    pageContext.setAttribute( "errors",                  errors );
88    pageContext.setAttribute( "plaintextConfiguration",  plaintextConfiguration );
89    pageContext.setAttribute( "legacymodeConfiguration", legacymodeConfiguration );
90    pageContext.setAttribute( "clientIdle",              ConnectionSettings.Client.IDLE_TIMEOUT_PROPERTY.getValue().toMillis());
91    pageContext.setAttribute( "pingIdleClients",         ConnectionSettings.Client.KEEP_ALIVE_PING_PROPERTY.getValue());
92
93
94%>
95<html>
96<head>
97    <title><fmt:message key="client.connections.settings.title"/></title>
98    <meta name="pageID" content="client-connections-settings"/>
99    <script type="text/javascript">
100        // Displays or hides the configuration block for a particular connection type, based on the status of the
101        // 'enable' checkbox for that connection type.
102        function applyDisplayable( connectionType )
103        {
104            var configBlock, enabled;
105
106            // Select the right configuration block and enable or disable it as defined by the the corresponding checkbox.
107            configBlock = document.getElementById( connectionType + "-config" );
108            enabled     = document.getElementById( connectionType + "-enabled" ).checked;
109
110            if ( ( configBlock != null ) && ( enabled != null ) )
111            {
112                if ( enabled )
113                {
114                    configBlock.style.display = "block";
115                }
116                else
117                {
118                    configBlock.style.display = "none";
119                }
120            }
121        }
122
123        // Ensure that the various elements are set properly when the page is loaded.
124        window.onload = function()
125        {
126            applyDisplayable( "plaintext" );
127            applyDisplayable( "legacymode" );
128        };
129    </script>
130</head>
131<body>
132
133<c:if test="${param.success and empty errors}">
134    <admin:infoBox type="success"><fmt:message key="client.connections.settings.confirm.updated" /></admin:infoBox>
135</c:if>
136
137<p>
138    <fmt:message key="client.connections.settings.info">
139        <fmt:param value="<a href=\"session-summary.jsp\">" />
140        <fmt:param value="</a>" />
141    </fmt:message>
142</p>
143
144<form action="connection-settings-socket-c2s.jsp" method="post">
145    <input type="hidden" name="csrf" value="${csrf}">
146
147    <fmt:message key="ssl.settings.client.plaintext.boxtitle" var="plaintextboxtitle"/>
148    <admin:contentBox title="${plaintextboxtitle}">
149
150        <p><fmt:message key="ssl.settings.client.plaintext.info"/></p>
151
152        <table cellpadding="3" cellspacing="0" border="0">
153            <tr valign="middle">
154                <td colspan="2"><input type="checkbox" name="plaintext-enabled" id="plaintext-enabled" onclick="applyDisplayable('plaintext')" ${plaintextConfiguration.enabled ? 'checked' : ''}/><label for="plaintext-enabled"><fmt:message key="ssl.settings.client.plaintext.label_enable"/></label></td>
155            </tr>
156            <tr valign="middle">
157                <td width="1%" nowrap><label for="plaintext-tcpPort"><fmt:message key="ports.port"/></label></td>
158                <td width="99%"><input type="text" name="plaintext-tcpPort" id="plaintext-tcpPort" value="${plaintextConfiguration.port}"/></td>
159            </tr>
160            <tr valign="middle">
161                <td colspan="2"><a href="./connection-settings-advanced.jsp?connectionType=SOCKET_C2S&connectionMode=plain"><fmt:message key="ssl.settings.client.label_custom_info"/>...</a></td>
162            </tr>
163        </table>
164
165    </admin:contentBox>
166
167    <fmt:message key="ssl.settings.client.legacymode.boxtitle" var="legacymodeboxtitle"/>
168    <admin:contentBox title="${legacymodeboxtitle}">
169
170        <p><fmt:message key="ssl.settings.client.legacymode.info"/></p>
171
172        <table cellpadding="3" cellspacing="0" border="0">
173            <tr valign="middle">
174                <td colspan="2"><input type="checkbox" name="legacymode-enabled" id="legacymode-enabled" onclick="applyDisplayable('legacymode')" ${legacymodeConfiguration.enabled ? 'checked' : ''}/><label for="legacymode-enabled"><fmt:message key="ssl.settings.client.legacymode.label_enable"/></label></td>
175            </tr>
176            <tr valign="middle">
177                <td width="1%" nowrap><label for="legacymode-tcpPort"><fmt:message key="ports.port"/></label></td>
178                <td width="99%"><input type="text" name="legacymode-tcpPort" id="legacymode-tcpPort" value="${legacymodeConfiguration.port}"></td>
179            </tr>
180            <tr valign="middle">
181                <td colspan="2"><a href="./connection-settings-advanced.jsp?connectionType=SOCKET_C2S&connectionMode=legacy"><fmt:message key="ssl.settings.client.label_custom_info"/>...</a></td>
182            </tr>
183        </table>
184
185    </admin:contentBox>
186
187    <!-- BEGIN 'Idle Connection Policy' -->
188    <fmt:message key="client.connections.settings.idle.title" var="idleTitle" />
189    <admin:contentBox title="${idleTitle}">
190        <p><fmt:message key="client.connections.settings.idle.info" /></p>
191        <table cellpadding="3" cellspacing="0" border="0" width="100%">
192            <tbody>
193            <tr valign="top">
194                <td width="1%" nowrap class="c1">
195                    <input type="radio" name="idleDisco" value="false" ${clientIdle le 0 ? 'checked' : ''} id="IDL01">
196                </td>
197                <td width="99%"><label for="IDL01"><fmt:message key="client.connections.settings.idle.disable" /></label></td>
198            </tr>
199            <tr valign="top">
200                <td width="1%" nowrap class="c1">
201                    <input type="radio" name="idleDisco" value="true" ${clientIdle gt 0 ? 'checked' : ''} id="IDL02">
202                </td>
203                <td width="99%">
204                    <label for="IDL02"><fmt:message key="client.connections.settings.idle.enable" /></label>
205                    <br />
206                    <c:if test="${clientIdle gt 0}">
207                        <fmt:parseNumber integerOnly="true" var="seconds">${clientIdle div 1000}</fmt:parseNumber>
208                    </c:if>
209                    <input type="text" name="clientIdle" value="${clientIdle gt 0 ? seconds : ''}" size="5" maxlength="5">&nbsp;<fmt:message key="global.seconds" />
210                    <c:if test="${not empty errors['clientIdle']}">
211                        <br/>
212                        <span class="jive-error-text">
213                            <fmt:message key="client.connections.settings.idle.valid_timeout" />.
214                        </span>
215                    </c:if>
216                </td>
217            </tr>
218            <tr><td colspan="2">&nbsp;</td></tr>
219            <tr>
220                <td>&nbsp;</td>
221                <td>
222                    <p><fmt:message key="client.connections.settings.ping.info" />
223                        <fmt:message key="client.connections.settings.ping.footnote" /></p>
224                    <table cellpadding="3" cellspacing="0" border="0" width="100%">
225                        <tbody>
226                        <tr valign="top">
227                            <td width="1%" nowrap class="c1">
228                                <input type="radio" name="pingIdleClients" value="true" ${pingIdleClients ? 'checked' : ''} id="PNG01">
229                            </td>
230                            <td width="99%"><label for="PNG01"><fmt:message key="client.connections.settings.ping.enable" /></label></td>
231                        </tr>
232                        <tr valign="top">
233                            <td width="1%" nowrap class="c1">
234                                <input type="radio" name="pingIdleClients" value="false" ${pingIdleClients ? '' : 'checked'} id="PNG02">
235                            </td>
236                            <td width="99%"><label for="PNG02"><fmt:message key="client.connections.settings.ping.disable" /></label></td>
237                        </tr>
238                        </tbody>
239                    </table>
240                </td>
241            </tr>
242            </tbody>
243        </table>
244    </admin:contentBox>
245
246    <!-- END 'Idle Connection Policy' -->
247
248    <input type="submit" name="update" value="<fmt:message key="global.save_settings" />">
249</form>
250</body>
251</html>
252