001    /**
002     * Copyright (c) 2000-2013 Liferay, Inc. All rights reserved.
003     *
004     * This library is free software; you can redistribute it and/or modify it under
005     * the terms of the GNU Lesser General Public License as published by the Free
006     * Software Foundation; either version 2.1 of the License, or (at your option)
007     * any later version.
008     *
009     * This library is distributed in the hope that it will be useful, but WITHOUT
010     * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
011     * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
012     * details.
013     */
014    
015    package com.liferay.portal.license.util;
016    
017    import com.liferay.portal.kernel.cluster.ClusterExecutorUtil;
018    import com.liferay.portal.kernel.cluster.ClusterNode;
019    import com.liferay.portal.kernel.cluster.ClusterNodeResponse;
020    import com.liferay.portal.kernel.cluster.ClusterNodeResponses;
021    import com.liferay.portal.kernel.cluster.ClusterRequest;
022    import com.liferay.portal.kernel.cluster.FutureClusterResponses;
023    import com.liferay.portal.kernel.json.JSONFactoryUtil;
024    import com.liferay.portal.kernel.json.JSONObject;
025    import com.liferay.portal.kernel.log.Log;
026    import com.liferay.portal.kernel.log.LogFactoryUtil;
027    import com.liferay.portal.kernel.util.Base64;
028    import com.liferay.portal.kernel.util.CharPool;
029    import com.liferay.portal.kernel.util.Constants;
030    import com.liferay.portal.kernel.util.ContentTypes;
031    import com.liferay.portal.kernel.util.FileUtil;
032    import com.liferay.portal.kernel.util.GetterUtil;
033    import com.liferay.portal.kernel.util.Http;
034    import com.liferay.portal.kernel.util.MethodHandler;
035    import com.liferay.portal.kernel.util.MethodKey;
036    import com.liferay.portal.kernel.util.ParamUtil;
037    import com.liferay.portal.kernel.util.ReleaseInfo;
038    import com.liferay.portal.kernel.util.StringPool;
039    import com.liferay.portal.kernel.util.StringUtil;
040    import com.liferay.portal.kernel.util.Validator;
041    import com.liferay.portal.util.ClassLoaderUtil;
042    import com.liferay.portal.util.PortalUtil;
043    import com.liferay.portal.util.PropsUtil;
044    import com.liferay.portal.util.PropsValues;
045    import com.liferay.util.Encryptor;
046    
047    import java.io.File;
048    import java.io.InputStream;
049    
050    import java.net.Inet4Address;
051    import java.net.InetAddress;
052    import java.net.NetworkInterface;
053    import java.net.URI;
054    import java.net.URL;
055    
056    import java.security.Key;
057    import java.security.KeyFactory;
058    import java.security.PublicKey;
059    import java.security.SecureRandom;
060    import java.security.spec.X509EncodedKeySpec;
061    
062    import java.util.Arrays;
063    import java.util.Collections;
064    import java.util.HashMap;
065    import java.util.HashSet;
066    import java.util.Iterator;
067    import java.util.List;
068    import java.util.Map;
069    import java.util.Set;
070    import java.util.TreeMap;
071    import java.util.concurrent.TimeUnit;
072    import java.util.regex.Matcher;
073    import java.util.regex.Pattern;
074    
075    import javax.crypto.KeyGenerator;
076    
077    import javax.servlet.http.HttpServletRequest;
078    
079    import org.apache.commons.io.IOUtils;
080    import org.apache.http.HttpEntity;
081    import org.apache.http.HttpHost;
082    import org.apache.http.HttpResponse;
083    import org.apache.http.auth.AuthScope;
084    import org.apache.http.auth.UsernamePasswordCredentials;
085    import org.apache.http.client.CredentialsProvider;
086    import org.apache.http.client.methods.HttpPost;
087    import org.apache.http.conn.ClientConnectionManager;
088    import org.apache.http.conn.params.ConnRoutePNames;
089    import org.apache.http.entity.ByteArrayEntity;
090    import org.apache.http.impl.client.DefaultHttpClient;
091    import org.apache.http.params.HttpParams;
092    
093    /**
094     * @author Amos Fong
095     */
096    public class LicenseUtil {
097    
098            public static final String LICENSE_REPOSITORY_DIR =
099                    PropsValues.LIFERAY_HOME.concat("/data/license");
100    
101            public static final String LICENSE_SERVER_URL = GetterUtil.get(
102                    PropsUtil.get("license.server.url"), "https://www.liferay.com");
103    
104            public static Map<String, String> getClusterServerInfo(String clusterNodeId)
105                    throws Exception {
106    
107                    List<ClusterNode> clusterNodes = ClusterExecutorUtil.getClusterNodes();
108    
109                    ClusterNode clusterNode = null;
110    
111                    for (ClusterNode curClusterNode : clusterNodes) {
112                            String curClusterNodeId = curClusterNode.getClusterNodeId();
113    
114                            if (curClusterNodeId.equals(clusterNodeId)) {
115                                    clusterNode = curClusterNode;
116    
117                                    break;
118                            }
119                    }
120    
121                    if (clusterNode == null) {
122                            return null;
123                    }
124    
125                    try {
126                            if (clusterNode.equals(ClusterExecutorUtil.getLocalClusterNode())) {
127                                    return getServerInfo();
128                            }
129    
130                            ClusterRequest clusterRequest = ClusterRequest.createUnicastRequest(
131                                    _getServerInfoMethodHandler, clusterNodeId);
132    
133                            FutureClusterResponses futureClusterResponses =
134                                    ClusterExecutorUtil.execute(clusterRequest);
135    
136                            ClusterNodeResponses clusterNodeResponses =
137                                    futureClusterResponses.get(20000, TimeUnit.MILLISECONDS);
138    
139                            ClusterNodeResponse clusterNodeResponse =
140                                    clusterNodeResponses.getClusterResponse(clusterNode);
141    
142                            return (Map<String, String>)clusterNodeResponse.getResult();
143                    }
144                    catch (Exception e) {
145                            _log.error(e, e);
146    
147                            throw e;
148                    }
149            }
150    
151            /**
152             * @deprecated As of 6.2.0, replaced by {@link PortalUtil#getComputerName()}
153             */
154            public static String getHostName() {
155                    return PortalUtil.getComputerName();
156            }
157    
158            public static Set<String> getIpAddresses() {
159                    if (_ipAddresses != null) {
160                            return new HashSet<String>(_ipAddresses);
161                    }
162    
163                    _ipAddresses = new HashSet<String>();
164    
165                    try {
166                            List<NetworkInterface> networkInterfaces = Collections.list(
167                                    NetworkInterface.getNetworkInterfaces());
168    
169                            for (NetworkInterface networkInterface : networkInterfaces) {
170                                    List<InetAddress> inetAddresses = Collections.list(
171                                            networkInterface.getInetAddresses());
172    
173                                    for (InetAddress inetAddress : inetAddresses) {
174                                            if (inetAddress.isLinkLocalAddress() ||
175                                                    inetAddress.isLoopbackAddress() ||
176                                                    !(inetAddress instanceof Inet4Address)) {
177    
178                                                    continue;
179                                            }
180    
181                                            _ipAddresses.add(inetAddress.getHostAddress());
182                                    }
183                            }
184                    }
185                    catch (Exception e) {
186                            _log.error("Unable to read local server's IP addresses");
187    
188                            _log.error(e, e);
189                    }
190    
191                    return new HashSet<String>(_ipAddresses);
192            }
193    
194            public static Set<String> getMacAddresses() {
195                    if (_macAddresses != null) {
196                            return new HashSet<String>(_macAddresses);
197                    }
198    
199                    Set<String> macAddresses = new HashSet<String>();
200    
201                    String osName = System.getProperty("os.name");
202    
203                    String executable = null;
204                    String arguments = null;
205    
206                    if (StringUtil.startsWith(osName, "win")) {
207                            executable = "ipconfig";
208                            arguments = "/all";
209                    }
210                    else {
211                            if (StringUtil.startsWith(osName, "aix")) {
212                                    executable = "netstat";
213                                    arguments = "-ina";
214                            }
215                            else {
216                                    executable = "ifconfig";
217                                    arguments = "-a";
218                            }
219    
220                            File sbinDir = new File("/sbin", executable);
221    
222                            if (sbinDir.exists()) {
223                                    executable = "/sbin/".concat(executable);
224                            }
225                    }
226    
227                    try {
228                            Runtime runtime = Runtime.getRuntime();
229    
230                            Process process = runtime.exec(
231                                    new String[] {executable, arguments});
232    
233                            macAddresses = getMacAddresses(osName, process.getInputStream());
234                    }
235                    catch (Exception e) {
236                            _log.error(e, e);
237                    }
238    
239                    _macAddresses = macAddresses;
240    
241                    return new HashSet<String>(macAddresses);
242            }
243    
244            public static Set<String> getMacAddresses(
245                            String osName, InputStream processInputStream)
246                    throws Exception {
247    
248                    Set<String> macAddresses = new HashSet<String>();
249    
250                    Pattern macAddressPattern = _macAddressPattern1;
251    
252                    if (StringUtil.startsWith(osName, "aix")) {
253                            macAddressPattern = _macAddressPattern2;
254                    }
255    
256                    String processOutput = StringUtil.read(processInputStream);
257    
258                    String[] lines = StringUtil.split(processOutput, CharPool.NEW_LINE);
259    
260                    for (String line : lines) {
261                            Matcher matcher = macAddressPattern.matcher(line);
262    
263                            if (!matcher.find()) {
264                                    continue;
265                            }
266    
267                            String macAddress = matcher.group(1);
268    
269                            macAddress = StringUtil.toLowerCase(macAddress);
270                            macAddress = macAddress.replace(CharPool.DASH, CharPool.COLON);
271                            macAddress = macAddress.replace(CharPool.PERIOD, CharPool.COLON);
272    
273                            StringBuilder sb = new StringBuilder(17);
274    
275                            sb.append(macAddress);
276    
277                            for (int i = 1; i < 5; ++i) {
278                                    int pos = (i * 3) - 1;
279    
280                                    if (sb.charAt(pos) != CharPool.COLON) {
281                                            sb.insert((i - 1) * 3, CharPool.NUMBER_0);
282                                    }
283                            }
284    
285                            if (sb.length() < 17) {
286                                    sb.insert(15, CharPool.NUMBER_0);
287                            }
288    
289                            macAddress = sb.toString();
290    
291                            macAddresses.add(macAddress);
292                    }
293    
294                    return macAddresses;
295            }
296    
297            public static byte[] getServerIdBytes() throws Exception {
298                    if (_serverIdBytes != null) {
299                            return _serverIdBytes;
300                    }
301    
302                    File serverIdFile = new File(
303                            LICENSE_REPOSITORY_DIR + "/server/serverId");
304    
305                    if (!serverIdFile.exists()) {
306                            return new byte[0];
307                    }
308    
309                    _serverIdBytes = FileUtil.getBytes(serverIdFile);
310    
311                    return _serverIdBytes;
312            }
313    
314            public static Map<String, String> getServerInfo() {
315                    Map<String, String> serverInfo = new HashMap<String, String>();
316    
317                    serverInfo.put("hostName", PortalUtil.getComputerName());
318                    serverInfo.put("ipAddresses", StringUtil.merge(getIpAddresses()));
319                    serverInfo.put("macAddresses", StringUtil.merge(getMacAddresses()));
320    
321                    return serverInfo;
322            }
323    
324            public static void registerOrder(HttpServletRequest request) {
325                    String orderUuid = ParamUtil.getString(request, "orderUuid");
326                    String productEntryName = ParamUtil.getString(
327                            request, "productEntryName");
328                    int maxServers = ParamUtil.getInteger(request, "maxServers");
329    
330                    List<ClusterNode> clusterNodes = ClusterExecutorUtil.getClusterNodes();
331    
332                    if ((clusterNodes.size() <= 1) || Validator.isNull(productEntryName) ||
333                            Validator.isNull(orderUuid)) {
334    
335                            Map<String, Object> attributes = registerOrder(
336                                    orderUuid, productEntryName, maxServers);
337    
338                            for (Map.Entry<String, Object> entry : attributes.entrySet()) {
339                                    request.setAttribute(entry.getKey(), entry.getValue());
340                            }
341                    }
342                    else {
343                            for (ClusterNode clusterNode : clusterNodes) {
344                                    boolean register = ParamUtil.getBoolean(
345                                            request, clusterNode.getClusterNodeId() + "_register");
346    
347                                    if (!register) {
348                                            continue;
349                                    }
350    
351                                    try {
352                                            _registerClusterOrder(
353                                                    request, clusterNode, orderUuid, productEntryName,
354                                                    maxServers);
355                                    }
356                                    catch (Exception e) {
357                                            _log.error(e, e);
358    
359                                            InetAddress inetAddress = clusterNode.getInetAddress();
360    
361                                            String message =
362                                                    "Error contacting " + inetAddress.getHostName();
363    
364                                            if (clusterNode.getPort() != -1) {
365                                                    message += StringPool.COLON + clusterNode.getPort();
366                                            }
367    
368                                            request.setAttribute(
369                                                    clusterNode.getClusterNodeId() + "_ERROR_MESSAGE",
370                                                    message);
371                                    }
372                            }
373                    }
374            }
375    
376            public static Map<String, Object> registerOrder(
377                    String orderUuid, String productEntryName, int maxServers) {
378    
379                    Map<String, Object> attributes = new HashMap<String, Object>();
380    
381                    if (Validator.isNull(orderUuid)) {
382                            return attributes;
383                    }
384    
385                    try {
386                            JSONObject jsonObject = _createRequest(
387                                    orderUuid, productEntryName, maxServers);
388    
389                            String response = sendRequest(jsonObject.toString());
390    
391                            JSONObject responseJSONObject = JSONFactoryUtil.createJSONObject(
392                                    response);
393    
394                            attributes.put(
395                                    "ORDER_PRODUCT_ID", responseJSONObject.getString("productId"));
396                            attributes.put(
397                                    "ORDER_PRODUCTS", _getOrderProducts(responseJSONObject));
398    
399                            String errorMessage = responseJSONObject.getString("errorMessage");
400    
401                            if (Validator.isNotNull(errorMessage)) {
402                                    attributes.put("ERROR_MESSAGE", errorMessage);
403    
404                                    return attributes;
405                            }
406    
407                            String licenseXML = responseJSONObject.getString("licenseXML");
408    
409                            if (Validator.isNotNull(licenseXML)) {
410                                    LicenseManagerUtil.registerLicense(responseJSONObject);
411    
412                                    attributes.clear();
413                                    attributes.put(
414                                            "SUCCESS_MESSAGE",
415                                            "Your license has been successfully registered.");
416                            }
417                    }
418                    catch (Exception e) {
419                            _log.error(e, e);
420    
421                            attributes.put(
422                                    "ERROR_MESSAGE",
423                                    "There was an error contacting " + LICENSE_SERVER_URL);
424                    }
425    
426                    return attributes;
427            }
428    
429            public static String sendRequest(String request) throws Exception {
430                    DefaultHttpClient defaultHttpClient = new DefaultHttpClient();
431    
432                    try {
433                            String serverURL = LICENSE_SERVER_URL;
434    
435                            if (!serverURL.endsWith(StringPool.SLASH)) {
436                                    serverURL += StringPool.SLASH;
437                            }
438    
439                            serverURL += "osb-portlet/license";
440    
441                            URI uri = new URI(serverURL);
442    
443                            HttpPost httpPost = new HttpPost(uri);
444    
445                            if (Validator.isNotNull(_PROXY_URL)) {
446                                    if (_log.isInfoEnabled()) {
447                                            _log.info(
448                                                    "Using proxy " + _PROXY_URL + StringPool.COLON +
449                                                            _PROXY_PORT);
450                                    }
451    
452                                    HttpHost httpHost = new HttpHost(_PROXY_URL, _PROXY_PORT);
453    
454                                    HttpParams httpParams = defaultHttpClient.getParams();
455    
456                                    httpParams.setParameter(
457                                            ConnRoutePNames.DEFAULT_PROXY, httpHost);
458    
459                                    if (Validator.isNotNull(_PROXY_USER_NAME)) {
460                                            CredentialsProvider credentialsProvider =
461                                                    defaultHttpClient.getCredentialsProvider();
462    
463                                            credentialsProvider.setCredentials(
464                                                    new AuthScope(_PROXY_URL, _PROXY_PORT),
465                                                    new UsernamePasswordCredentials(
466                                                            _PROXY_USER_NAME, _PROXY_PASSWORD));
467                                    }
468                            }
469    
470                            ByteArrayEntity byteArrayEntity = new ByteArrayEntity(
471                                    _encryptRequest(serverURL, request));
472    
473                            byteArrayEntity.setContentType(ContentTypes.APPLICATION_JSON);
474    
475                            httpPost.setEntity(byteArrayEntity);
476    
477                            HttpResponse httpResponse = defaultHttpClient.execute(httpPost);
478    
479                            HttpEntity httpEntity = httpResponse.getEntity();
480    
481                            String response = _decryptResponse(
482                                    serverURL, httpEntity.getContent());
483    
484                            if (_log.isDebugEnabled()) {
485                                    _log.debug("Server response: " + response);
486                            }
487    
488                            if (Validator.isNull(response)) {
489                                    throw new Exception("Server response is null");
490                            }
491    
492                            return response;
493                    }
494                    finally {
495                            ClientConnectionManager clientConnectionManager =
496                                    defaultHttpClient.getConnectionManager();
497    
498                            clientConnectionManager.shutdown();
499                    }
500            }
501    
502            public static void writeServerProperties(byte[] serverIdBytes)
503                    throws Exception {
504    
505                    File serverIdFile = new File(
506                            LICENSE_REPOSITORY_DIR + "/server/serverId");
507    
508                    FileUtil.write(serverIdFile, serverIdBytes);
509            }
510    
511            private static JSONObject _createRequest(
512                            String orderUuid, String productEntryName, int maxServers)
513                    throws Exception {
514    
515                    JSONObject jsonObject = JSONFactoryUtil.createJSONObject();
516    
517                    jsonObject.put("version", 2);
518                    jsonObject.put("orderUuid", orderUuid);
519                    jsonObject.put("liferayVersion", ReleaseInfo.getBuildNumber());
520    
521                    if (Validator.isNull(productEntryName)) {
522                            jsonObject.put(Constants.CMD, "QUERY");
523                    }
524                    else {
525                            jsonObject.put(Constants.CMD, "REGISTER");
526    
527                            if (productEntryName.startsWith("basic")) {
528                                    jsonObject.put("productEntryName", "basic");
529    
530                                    if (productEntryName.equals("basic-cluster")) {
531                                            jsonObject.put("cluster", true);
532                                            jsonObject.put("maxServers", maxServers);
533                                    }
534                                    else if (productEntryName.startsWith("basic-")) {
535                                            String[] productNameArray = StringUtil.split(
536                                                    productEntryName, StringPool.DASH);
537    
538                                            if (productNameArray.length >= 3) {
539                                                    jsonObject.put("offeringEntryId", productNameArray[1]);
540                                                    jsonObject.put("clusterId", productNameArray[2]);
541                                            }
542                                    }
543                            }
544                            else {
545                                    jsonObject.put("productEntryName", productEntryName);
546                            }
547    
548                            jsonObject.put("hostName", PortalUtil.getComputerName());
549                            jsonObject.put("ipAddresses", StringUtil.merge(getIpAddresses()));
550                            jsonObject.put("macAddresses", StringUtil.merge(getMacAddresses()));
551                            jsonObject.put("serverId", Arrays.toString(getServerIdBytes()));
552                    }
553    
554                    return jsonObject;
555            }
556    
557            private static String _decryptResponse(
558                            String serverURL, InputStream inputStream)
559                    throws Exception {
560    
561                    if (serverURL.startsWith(Http.HTTPS)) {
562                            return StringUtil.read(inputStream);
563                    }
564    
565                    byte[] bytes = IOUtils.toByteArray(inputStream);
566    
567                    if ((bytes == null) || (bytes.length <= 0)) {
568                            return null;
569                    }
570    
571                    bytes = Encryptor.decryptUnencodedAsBytes(_symmetricKey, bytes);
572    
573                    return new String(bytes, StringPool.UTF8);
574            }
575    
576            private static byte[] _encryptRequest(String serverURL, String request)
577                    throws Exception {
578    
579                    byte[] bytes = request.getBytes(StringPool.UTF8);
580    
581                    if (serverURL.startsWith(Http.HTTPS)) {
582                            return bytes;
583                    }
584    
585                    JSONObject jsonObject = JSONFactoryUtil.createJSONObject();
586    
587                    bytes = Encryptor.encryptUnencoded(_symmetricKey, bytes);
588    
589                    jsonObject.put("content", Base64.objectToString(bytes));
590                    jsonObject.put("key", _encryptedSymmetricKey);
591    
592                    return jsonObject.toString().getBytes(StringPool.UTF8);
593            }
594    
595            private static Map<String, String> _getOrderProducts(
596                    JSONObject jsonObject) {
597    
598                    JSONObject productsJSONObject = jsonObject.getJSONObject(
599                            "productsJSONObject");
600    
601                    if (productsJSONObject == null) {
602                            return null;
603                    }
604    
605                    Map<String, String> sortedMap = new TreeMap<String, String>(
606                            String.CASE_INSENSITIVE_ORDER);
607    
608                    Iterator<String> itr = productsJSONObject.keys();
609    
610                    while (itr.hasNext()) {
611                            String key = itr.next();
612    
613                            sortedMap.put(key, productsJSONObject.getString(key));
614                    }
615    
616                    return sortedMap;
617            }
618    
619            private static void _initKeys() {
620                    ClassLoader classLoader = ClassLoaderUtil.getPortalClassLoader();
621    
622                    if ((classLoader == null) || (_encryptedSymmetricKey != null)) {
623                            return;
624                    }
625    
626                    try {
627                            URL url = classLoader.getResource(
628                                    "com/liferay/portal/license/public.key");
629    
630                            byte[] bytes = IOUtils.toByteArray(url.openStream());
631    
632                            X509EncodedKeySpec x509EncodedKeySpec = new X509EncodedKeySpec(
633                                    bytes);
634    
635                            KeyFactory keyFactory = KeyFactory.getInstance("RSA");
636    
637                            PublicKey publicKey = keyFactory.generatePublic(x509EncodedKeySpec);
638    
639                            KeyGenerator keyGenerator = KeyGenerator.getInstance("AES");
640    
641                            keyGenerator.init(128, new SecureRandom());
642    
643                            _symmetricKey = keyGenerator.generateKey();
644    
645                            byte[] encryptedSymmetricKey = Encryptor.encryptUnencoded(
646                                    publicKey, _symmetricKey.getEncoded());
647    
648                            _encryptedSymmetricKey = Base64.objectToString(
649                                    encryptedSymmetricKey);
650                    }
651                    catch (Exception e) {
652                            _log.error(e, e);
653                    }
654            }
655    
656            private static void _registerClusterOrder(
657                            HttpServletRequest request, ClusterNode clusterNode,
658                            String orderUuid, String productEntryName, int maxServers)
659                    throws Exception {
660    
661                    MethodHandler methodHandler = new MethodHandler(
662                            _registerOrderMethodKey, orderUuid, productEntryName, maxServers);
663    
664                    ClusterRequest clusterRequest = ClusterRequest.createUnicastRequest(
665                            methodHandler, clusterNode.getClusterNodeId());
666    
667                    FutureClusterResponses futureClusterResponses =
668                            ClusterExecutorUtil.execute(clusterRequest);
669    
670                    ClusterNodeResponses clusterNodeResponses = futureClusterResponses.get(
671                            20000, TimeUnit.MILLISECONDS);
672    
673                    ClusterNodeResponse clusterNodeResponse =
674                            clusterNodeResponses.getClusterResponse(clusterNode);
675    
676                    Map<String, Object> attributes =
677                            (Map<String, Object>)clusterNodeResponse.getResult();
678    
679                    for (Map.Entry<String, Object> entry : attributes.entrySet()) {
680                            request.setAttribute(
681                                    clusterNode.getClusterNodeId() + StringPool.UNDERLINE +
682                                            entry.getKey(),
683                                    entry.getValue());
684                    }
685            }
686    
687            private static final String _PROXY_PASSWORD = GetterUtil.getString(
688                    PropsUtil.get("license.proxy.password"));
689    
690            private static final int _PROXY_PORT = GetterUtil.getInteger(
691                    PropsUtil.get("license.proxy.port"), 80);
692    
693            private static final String _PROXY_URL = PropsUtil.get("license.proxy.url");
694    
695            private static final String _PROXY_USER_NAME = GetterUtil.getString(
696                    PropsUtil.get("license.proxy.username"));
697    
698            private static Log _log = LogFactoryUtil.getLog(LicenseUtil.class);
699    
700            private static String _encryptedSymmetricKey;
701            private static MethodHandler _getServerInfoMethodHandler =
702                    new MethodHandler(new MethodKey(LicenseUtil.class, "getServerInfo"));
703            private static Set<String> _ipAddresses;
704            private static Set<String> _macAddresses;
705            private static Pattern _macAddressPattern1 = Pattern.compile(
706                    "\\s((\\p{XDigit}{1,2}(-|:)){5}(\\p{XDigit}{1,2}))(?:\\s|$)");
707            private static Pattern _macAddressPattern2 = Pattern.compile(
708                    "\\s((\\p{XDigit}{1,2}(\\.)){5}(\\p{XDigit}{1,2}))(?:\\s|$)");
709            private static MethodKey _registerOrderMethodKey = new MethodKey(
710                    LicenseUtil.class, "registerOrder", String.class, String.class,
711                    int.class);
712            private static byte[] _serverIdBytes;
713            private static Key _symmetricKey;
714    
715            static {
716                    _initKeys();
717            }
718    
719    }