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