1   
2   
3   
4   
5   
6   
7   
8   
9   
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  package org.waarp.openr66.database.data;
21  
22  import com.fasterxml.jackson.core.Base64Variants;
23  import com.fasterxml.jackson.databind.JsonNode;
24  import com.fasterxml.jackson.databind.node.ArrayNode;
25  import com.fasterxml.jackson.databind.node.ObjectNode;
26  import org.waarp.common.database.DbConstant;
27  import org.waarp.common.database.DbPreparedStatement;
28  import org.waarp.common.database.DbSession;
29  import org.waarp.common.database.exception.WaarpDatabaseException;
30  import org.waarp.common.database.exception.WaarpDatabaseNoConnectionException;
31  import org.waarp.common.database.exception.WaarpDatabaseNoDataException;
32  import org.waarp.common.database.exception.WaarpDatabaseSqlException;
33  import org.waarp.common.digest.FilesystemBasedDigest;
34  import org.waarp.common.json.JsonHandler;
35  import org.waarp.common.logging.WaarpLogger;
36  import org.waarp.common.logging.WaarpLoggerFactory;
37  import org.waarp.common.role.RoleDefault;
38  import org.waarp.common.utility.ParametersChecker;
39  import org.waarp.common.utility.WaarpStringUtils;
40  import org.waarp.openr66.context.R66Session;
41  import org.waarp.openr66.dao.AbstractDAO;
42  import org.waarp.openr66.dao.DAOFactory;
43  import org.waarp.openr66.dao.Filter;
44  import org.waarp.openr66.dao.HostDAO;
45  import org.waarp.openr66.dao.database.DBHostDAO;
46  import org.waarp.openr66.dao.database.StatementExecutor;
47  import org.waarp.openr66.dao.exception.DAOConnectionException;
48  import org.waarp.openr66.dao.exception.DAONoDataException;
49  import org.waarp.openr66.pojo.Host;
50  import org.waarp.openr66.protocol.configuration.Configuration;
51  import org.waarp.openr66.protocol.networkhandler.NetworkTransaction;
52  
53  import java.net.InetSocketAddress;
54  import java.net.SocketAddress;
55  import java.sql.SQLException;
56  import java.sql.Types;
57  import java.util.ArrayList;
58  import java.util.List;
59  import java.util.regex.Matcher;
60  import java.util.regex.Pattern;
61  
62  
63  
64  
65  public class DbHostAuth extends AbstractDbDataDao<Host> {
66    private static final String CHECKED = "checked";
67  
68    private static final String CANNOT_FIND_HOST = "Cannot find host";
69  
70    public static final String DEFAULT_CLIENT_ADDRESS = "0.0.0.0";
71  
72    
73  
74  
75    private static final WaarpLogger logger =
76        WaarpLoggerFactory.getLogger(DbHostAuth.class);
77    private static final byte[] VALUE_0_BYTE = {};
78    private static final DbHostAuth[] DBHOSTAUTH_0_SIZE = new DbHostAuth[0];
79    private static final Pattern BACKSLASH =
80        Pattern.compile("\"", Pattern.LITERAL);
81    private static final Pattern COMMA = Pattern.compile(",", Pattern.LITERAL);
82  
83    public enum Columns {
84      ADDRESS, PORT, ISSSL, HOSTKEY, ADMINROLE, ISCLIENT, ISACTIVE, ISPROXIFIED,
85      UPDATEDINFO, HOSTID
86    }
87  
88    public static final int[] dbTypes = {
89        Types.NVARCHAR, Types.INTEGER, Types.BIT, Types.VARBINARY, Types.BIT,
90        Types.BIT, Types.BIT, Types.BIT, Types.INTEGER, Types.NVARCHAR
91    };
92  
93    public static final String table = " HOSTS ";
94  
95    protected static final String selectAllFields =
96        Columns.ADDRESS.name() + ',' + Columns.PORT.name() + ',' +
97        Columns.ISSSL.name() + ',' + Columns.HOSTKEY.name() + ',' +
98        Columns.ADMINROLE.name() + ',' + Columns.ISCLIENT.name() + ',' +
99        Columns.ISACTIVE.name() + ',' + Columns.ISPROXIFIED.name() + ',' +
100       Columns.UPDATEDINFO.name() + ',' + Columns.HOSTID.name();
101 
102   public static final Columns[] indexes = {
103       Columns.UPDATEDINFO
104   };
105 
106   @Override
107   protected final void initObject() {
108     
109   }
110 
111   @Override
112   protected final String getTable() {
113     return table;
114   }
115 
116   @Override
117   protected final AbstractDAO<Host> getDao(final boolean isCacheable)
118       throws DAOConnectionException {
119     return DAOFactory.getInstance().getHostDAO(isCacheable);
120   }
121 
122   @Override
123   protected final String getPrimaryKey() {
124     if (pojo != null) {
125       return pojo.getHostid();
126     }
127     throw new IllegalArgumentException("pojo is null");
128   }
129 
130   @Override
131   protected final String getPrimaryField() {
132     return Columns.HOSTID.name();
133   }
134 
135   
136 
137 
138 
139 
140 
141 
142 
143 
144   public DbHostAuth(final String hostid, final String address, final int port,
145                     final boolean isSSL, final byte[] hostkey,
146                     final boolean adminrole, final boolean isClient)
147       throws WaarpDatabaseSqlException {
148     pojo = new Host(hostid, address, port, hostkey, isSSL, isClient, false,
149                     adminrole);
150     if (hostkey != null) {
151       try {
152         
153         pojo.setHostkey(
154             Configuration.configuration.getCryptoKey().cryptToHex(hostkey)
155                                        .getBytes(WaarpStringUtils.UTF8));
156       } catch (final Exception e) {
157         logger.warn("Error while cyphering hostkey" + " : {}", e.getMessage());
158         pojo.setHostkey(VALUE_0_BYTE);
159       }
160     }
161     if (port < 0) {
162       pojo.setClient(true);
163       pojo.setAddress(DEFAULT_CLIENT_ADDRESS);
164     }
165     checkValues();
166     isSaved = false;
167   }
168 
169   private DbHostAuth(final Host host) {
170     if (host == null) {
171       throw new IllegalArgumentException(
172           "Argument in constructor cannot be null");
173     }
174     this.pojo = host;
175   }
176 
177   public DbHostAuth(final ObjectNode source) throws WaarpDatabaseSqlException {
178     pojo = new Host();
179     setFromJson(source, false);
180   }
181 
182   @Override
183   protected final void checkValues() throws WaarpDatabaseSqlException {
184     pojo.checkValues();
185   }
186 
187   @Override
188   public final void setFromJson(final ObjectNode node,
189                                 final boolean ignorePrimaryKey)
190       throws WaarpDatabaseSqlException {
191     super.setFromJson(node, ignorePrimaryKey);
192     if (pojo.getHostkey() == null || pojo.getHostkey().length == 0 ||
193         ParametersChecker.isEmpty(pojo.getAddress()) ||
194         ParametersChecker.isEmpty(pojo.getHostid())) {
195       throw new WaarpDatabaseSqlException(
196           "Not enough argument to create the object");
197     }
198     if (pojo.getHostkey() != null) {
199       try {
200         
201         pojo.setHostkey(Configuration.configuration.getCryptoKey().cryptToHex(
202             pojo.getHostkey()).getBytes(WaarpStringUtils.UTF8));
203       } catch (final Exception e) {
204         pojo.setHostkey(VALUE_0_BYTE);
205       }
206       isSaved = false;
207     }
208     if (pojo.getPort() < 0) {
209       pojo.setClient(true);
210       pojo.setAddress(DEFAULT_CLIENT_ADDRESS);
211       isSaved = false;
212     }
213     if (!ignorePrimaryKey) {
214       try {
215         insert();
216       } catch (final WaarpDatabaseException e) {
217         try {
218           update();
219         } catch (final WaarpDatabaseException ex) {
220           logger.error("Cannot save item: {}", ex.getMessage());
221         }
222       }
223     }
224   }
225 
226   @Override
227   protected final void setFromJson(final String field, final JsonNode value) {
228     if (value == null) {
229       return;
230     }
231     for (final Columns column : Columns.values()) {
232       if (column.name().equalsIgnoreCase(field)) {
233         switch (column) {
234           case ADDRESS:
235             pojo.setAddress(value.asText());
236             break;
237           case ADMINROLE:
238             pojo.setAdmin(value.asBoolean());
239             break;
240           case HOSTKEY:
241             
242             try {
243               final byte[] key =
244                   Base64Variants.getDefaultVariant().decode(value.asText());
245               pojo.setHostkey(key);
246             } catch (final IllegalArgumentException e) {
247               logger.warn("HostKey not in Base64 from Jackson: {}",
248                           e.getMessage());
249               pojo.setHostkey(value.asText().getBytes(WaarpStringUtils.UTF8));
250             }
251             break;
252           case ISACTIVE:
253             pojo.setActive(value.asBoolean());
254             break;
255           case ISCLIENT:
256             pojo.setClient(value.asBoolean());
257             break;
258           case ISPROXIFIED:
259             pojo.setProxified(value.asBoolean());
260             break;
261           case ISSSL:
262             pojo.setSSL(value.asBoolean());
263             break;
264           case PORT:
265             pojo.setPort(value.asInt());
266             break;
267           case UPDATEDINFO:
268             pojo.setUpdatedInfo(
269                 org.waarp.openr66.pojo.UpdatedInfo.valueOf(value.asInt()));
270             break;
271           case HOSTID:
272             pojo.setHostid(value.asText());
273             break;
274         }
275       }
276     }
277   }
278 
279   
280 
281 
282 
283 
284   public DbHostAuth(final String hostid) throws WaarpDatabaseException {
285     if (hostid == null) {
286       throw new WaarpDatabaseException("No host id passed");
287     }
288     HostDAO hostAccess = null;
289     try {
290       hostAccess = DAOFactory.getInstance().getHostDAO(true);
291       pojo = hostAccess.select(hostid);
292     } catch (final DAOConnectionException e) {
293       throw new WaarpDatabaseException(e);
294     } catch (final DAONoDataException e) {
295       throw new WaarpDatabaseNoDataException(CANNOT_FIND_HOST, e);
296     } finally {
297       DAOFactory.closeDAO(hostAccess);
298     }
299   }
300 
301   
302 
303 
304 
305 
306 
307 
308   public static DbHostAuth[] deleteAll() throws WaarpDatabaseException {
309     HostDAO hostAccess = null;
310     final List<DbHostAuth> res = new ArrayList<DbHostAuth>();
311     List<Host> hosts;
312     try {
313       hostAccess = DAOFactory.getInstance().getHostDAO(false);
314       hosts = hostAccess.getAll();
315       hostAccess.deleteAll();
316     } catch (final DAOConnectionException e) {
317       throw new WaarpDatabaseException(e);
318     } finally {
319       DAOFactory.closeDAO(hostAccess);
320     }
321     for (final Host host : hosts) {
322       final DbHostAuth hostAuth = new DbHostAuth(host);
323       hostAuth.isSaved = false;
324       res.add(hostAuth);
325     }
326     return res.toArray(new DbHostAuth[0]);
327   }
328 
329   
330 
331 
332   private DbHostAuth() {
333     pojo = new Host();
334   }
335 
336   
337 
338 
339 
340 
341 
342 
343 
344 
345   public static DbHostAuth[] getAllHosts()
346       throws WaarpDatabaseNoConnectionException {
347     HostDAO hostAccess = null;
348     final List<DbHostAuth> res = new ArrayList<DbHostAuth>();
349     List<Host> hosts;
350     try {
351       hostAccess = DAOFactory.getInstance().getHostDAO(false);
352       hosts = hostAccess.getAll();
353     } catch (final DAOConnectionException e) {
354       throw new WaarpDatabaseNoConnectionException(e);
355     } finally {
356       DAOFactory.closeDAO(hostAccess);
357     }
358     for (final Host host : hosts) {
359       final DbHostAuth dbHostAuth = new DbHostAuth(host);
360       dbHostAuth.isSaved = true;
361       res.add(dbHostAuth);
362     }
363     return res.toArray(DBHOSTAUTH_0_SIZE);
364   }
365 
366   
367 
368 
369 
370 
371 
372 
373 
374 
375 
376   public static DbHostAuth getFromStatement(
377       final DbPreparedStatement preparedStatement)
378       throws WaarpDatabaseNoConnectionException, WaarpDatabaseSqlException {
379     final DbHostAuth dbHostAuth = new DbHostAuth();
380     AbstractDAO<Host> hostDAO = null;
381     try {
382       hostDAO = dbHostAuth.getDao(false);
383       dbHostAuth.pojo = ((StatementExecutor<Host>) hostDAO).getFromResultSet(
384           preparedStatement.getResultSet());
385       return dbHostAuth;
386     } catch (final SQLException e) {
387       DbConstant.error(e);
388       throw new WaarpDatabaseSqlException("Getting values in error", e);
389     } catch (final DAOConnectionException e) {
390       throw new WaarpDatabaseSqlException("Getting values in error", e);
391     } finally {
392       DAOFactory.closeDAO(hostDAO);
393     }
394   }
395 
396   public static DbHostAuth[] getUpdatedPreparedStatement()
397       throws WaarpDatabaseNoConnectionException {
398     final List<Filter> filters = new ArrayList<Filter>(1);
399     filters.add(new Filter(DBHostDAO.UPDATED_INFO_FIELD, "=",
400                            org.waarp.openr66.pojo.UpdatedInfo.fromLegacy(
401                                UpdatedInfo.TOSUBMIT).ordinal()));
402     HostDAO hostAccess = null;
403     List<Host> hosts;
404     try {
405       hostAccess = DAOFactory.getInstance().getHostDAO(false);
406       hosts = hostAccess.find(filters);
407     } catch (final DAOConnectionException e) {
408       throw new WaarpDatabaseNoConnectionException(e);
409     } finally {
410       DAOFactory.closeDAO(hostAccess);
411     }
412     final DbHostAuth[] res = new DbHostAuth[hosts.size()];
413     int i = 0;
414     for (final Host host : hosts) {
415       res[i] = new DbHostAuth(host);
416       i++;
417     }
418     return res;
419   }
420 
421   
422 
423 
424 
425 
426 
427 
428 
429 
430 
431 
432 
433   public static DbPreparedStatement getFilterPrepareStament(
434       final DbSession session, final String host, final String addr,
435       final boolean ssl, final boolean active)
436       throws WaarpDatabaseNoConnectionException, WaarpDatabaseSqlException {
437     final DbPreparedStatement preparedStatement =
438         new DbPreparedStatement(session);
439     final String request =
440         "SELECT " + selectAllFields + " FROM " + table + " WHERE ";
441     String condition = null;
442     if (ParametersChecker.isNotEmpty(host)) {
443       condition = Columns.HOSTID.name() + " = '" + host + "' ";
444     }
445     if (ParametersChecker.isNotEmpty(addr)) {
446       if (condition != null) {
447         condition += " AND ";
448       } else {
449         condition = "";
450       }
451       condition += Columns.ADDRESS.name() + " = '" + addr + "' ";
452     }
453     if (condition != null) {
454       condition += " AND ";
455     } else {
456       condition = "";
457     }
458     condition += Columns.ISSSL.name() + " = ? AND ";
459     condition += Columns.ISACTIVE.name() + " = ? ";
460     preparedStatement.createPrepareStatement(
461         request + condition + " ORDER BY " + Columns.HOSTID.name());
462     try {
463       preparedStatement.getPreparedStatement().setBoolean(1, ssl);
464       preparedStatement.getPreparedStatement().setBoolean(2, active);
465     } catch (final SQLException e) {
466       preparedStatement.realClose();
467       throw new WaarpDatabaseSqlException(e);
468     }
469     return preparedStatement;
470   }
471 
472   
473 
474 
475 
476 
477 
478 
479 
480 
481 
482   public static DbPreparedStatement getFilterPrepareStament(
483       final DbSession session, final String host, final String addr)
484       throws WaarpDatabaseNoConnectionException, WaarpDatabaseSqlException {
485     final DbPreparedStatement preparedStatement =
486         new DbPreparedStatement(session);
487     final String request = "SELECT " + selectAllFields + " FROM " + table;
488     String condition = null;
489     if (ParametersChecker.isNotEmpty(host)) {
490       condition = Columns.HOSTID.name() + " = '" + host + "' ";
491     }
492     if (ParametersChecker.isNotEmpty(addr)) {
493       if (condition != null) {
494         condition += " AND ";
495       } else {
496         condition = "";
497       }
498       condition += Columns.ADDRESS.name() + " = '" + addr + "' ";
499     }
500     if (condition != null) {
501       condition = " WHERE " + condition;
502     } else {
503       condition = "";
504     }
505     preparedStatement.createPrepareStatement(
506         request + condition + " ORDER BY " + Columns.HOSTID.name());
507     return preparedStatement;
508   }
509 
510   @Override
511   public final void changeUpdatedInfo(final UpdatedInfo info) {
512     isSaved = false;
513     pojo.setUpdatedInfo(org.waarp.openr66.pojo.UpdatedInfo.fromLegacy(info));
514   }
515 
516   
517 
518 
519   public final boolean isActive() {
520     return pojo.isActive();
521   }
522 
523   
524 
525 
526   public final void setActive(final boolean isActive) {
527     isSaved = false;
528     pojo.setActive(isActive);
529   }
530 
531   
532 
533 
534   public final boolean isProxified() {
535     return pojo.isProxified();
536   }
537 
538   
539 
540 
541   public final void setProxified(final boolean isProxified) {
542     isSaved = false;
543     pojo.setProxified(isProxified);
544   }
545 
546   
547 
548 
549 
550 
551 
552 
553   public final boolean isKeyValid(final byte[] newkey) {
554     
555     
556     if (pojo.getHostkey() == null) {
557       return true;
558     }
559     
560     if (newkey == null || !isActive()) {
561       return false;
562     }
563     try {
564       return FilesystemBasedDigest.equalPasswd(
565           Configuration.configuration.getCryptoKey()
566                                      .decryptHexInBytes(pojo.getHostkey()),
567           newkey);
568     } catch (final Exception e) {
569       logger.info("Error while checking key", e);
570       return false;
571     }
572   }
573 
574   
575 
576 
577   public final byte[] getHostkey() {
578     if (pojo.getHostkey() == null) {
579       return null;
580     }
581     try {
582       return Configuration.configuration.getCryptoKey()
583                                         .decryptHexInBytes(pojo.getHostkey());
584     } catch (final Exception e) {
585       logger.info("Error while checking key", e);
586       return VALUE_0_BYTE;
587     }
588   }
589 
590   
591 
592 
593   public final boolean isAdminrole() {
594     return pojo.isAdmin();
595   }
596 
597   
598 
599 
600 
601 
602   public final boolean isClient() {
603     return pojo.isClient() || isNoAddress();
604   }
605 
606   
607 
608 
609 
610 
611 
612   public final boolean isNoAddress() {
613     return pojo.getAddress().equals(DEFAULT_CLIENT_ADDRESS) ||
614            pojo.getPort() < 0;
615   }
616 
617   
618 
619 
620 
621 
622 
623 
624   public final SocketAddress getSocketAddress()
625       throws IllegalArgumentException {
626     if (isNoAddress()) {
627       throw new IllegalArgumentException("Not a server");
628     }
629     return new InetSocketAddress(pojo.getAddress(), pojo.getPort());
630   }
631 
632   
633 
634 
635   public final boolean isSsl() {
636     return pojo.isSSL();
637   }
638 
639   
640 
641 
642   public final String getHostid() {
643     return pojo.getHostid();
644   }
645 
646   
647 
648 
649   public final String getAddress() {
650     return pojo.getAddress();
651   }
652 
653   
654 
655 
656   public final int getPort() {
657     return pojo.getPort();
658   }
659 
660   private static String getVersion(final String host) {
661     String remoteHost = host;
662     String alias = "";
663     if (Configuration.configuration.getAliases().containsKey(remoteHost)) {
664       remoteHost = Configuration.configuration.getAliases().get(remoteHost);
665       alias += "(Alias: " + remoteHost + ") ";
666     }
667     if (Configuration.configuration.getReverseAliases()
668                                    .containsKey(remoteHost)) {
669       final StringBuilder alias2 = new StringBuilder("(ReverseAlias: ");
670       final String[] list =
671           Configuration.configuration.getReverseAliases().get(remoteHost);
672       boolean found = false;
673       for (final String string : list) {
674         if (string.equals(host)) {
675           continue;
676         }
677         found = true;
678         alias2.append(string).append(' ');
679       }
680       if (found) {
681         alias += alias2 + ") ";
682       }
683     }
684     if (Configuration.configuration.getBusinessWhiteSet()
685                                    .contains(remoteHost)) {
686       alias += "(Business: Allowed) ";
687     }
688     if (Configuration.configuration.getRoles().containsKey(remoteHost)) {
689       final RoleDefault item =
690           Configuration.configuration.getRoles().get(remoteHost);
691       alias += "(Role: " + item + ") ";
692     }
693     return alias +
694            (Configuration.configuration.getVersions().containsKey(remoteHost)?
695                Configuration.configuration.getVersions().get(remoteHost)
696                                           .toString() : "Version Unknown");
697   }
698 
699   @Override
700   public final String toString() {
701     return "HostAuth: " + getHostid() + " address: " + getAddress() + ':' +
702            getPort() + " isSSL: " + isSsl() + " admin: " + isAdminrole() +
703            " isClient: " + isClient() + " isActive: " + isActive() +
704            " isProxified: " + isProxified() + " (" +
705            (pojo.getHostkey() != null? pojo.getHostkey().length : 0) +
706            ") Version: " + getVersion(getHostid());
707   }
708 
709   
710 
711 
712 
713 
714 
715 
716 
717 
718 
719   public static String getJson(final DbPreparedStatement preparedStatement,
720                                final int limit)
721       throws WaarpDatabaseNoConnectionException, WaarpDatabaseSqlException {
722     final ArrayNode arrayNode = JsonHandler.createArrayNode();
723     try {
724       preparedStatement.executeQuery();
725       int nb = 0;
726       while (preparedStatement.getNext()) {
727         final DbHostAuth host = getFromStatement(preparedStatement);
728         final ObjectNode node = host.getInternalJson();
729         arrayNode.add(node);
730         nb++;
731         if (nb >= limit) {
732           break;
733         }
734       }
735     } finally {
736       preparedStatement.realClose();
737     }
738     return JsonHandler.writeAsString(arrayNode);
739   }
740 
741   private ObjectNode getInternalJson() {
742     final ObjectNode node = getJson();
743     try {
744       node.put(Columns.HOSTKEY.name(),
745                new String(getHostkey(), WaarpStringUtils.UTF8));
746     } catch (final Exception e1) {
747       node.put(Columns.HOSTKEY.name(), "");
748     }
749     int nb;
750     try {
751       nb = NetworkTransaction.nbAttachedConnection(getSocketAddress(),
752                                                    getHostid());
753     } catch (final Exception e) {
754       nb = -1;
755     }
756     node.put("Connection", nb);
757     node.put("Version", COMMA.matcher(BACKSLASH.matcher(getVersion(getHostid()))
758                                                .replaceAll(
759                                                    Matcher.quoteReplacement(
760                                                        "")))
761                              .replaceAll(Matcher.quoteReplacement(", ")));
762     return node;
763   }
764 
765   
766 
767 
768   public final String getJsonAsString() {
769     final ObjectNode node = getInternalJson();
770     return JsonHandler.writeAsString(node);
771   }
772 
773   
774 
775 
776 
777 
778 
779 
780 
781 
782 
783   public final String toSpecializedHtml(final R66Session session,
784                                         final String body,
785                                         final boolean crypted) {
786     final StringBuilder builder = new StringBuilder(body);
787     WaarpStringUtils.replace(builder, "XXXHOSTXXX", getHostid());
788     WaarpStringUtils.replace(builder, "XXXADDRXXX", getAddress());
789     WaarpStringUtils.replace(builder, "XXXPORTXXX",
790                              Integer.toString(getPort()));
791     if (crypted) {
792       WaarpStringUtils.replace(builder, "XXXKEYXXX",
793                                new String(getHostkey(), WaarpStringUtils.UTF8));
794     } else {
795       try {
796         WaarpStringUtils.replace(builder, "XXXKEYXXX", new String(getHostkey(),
797                                                                   WaarpStringUtils.UTF8));
798       } catch (final Exception e) {
799         WaarpStringUtils.replace(builder, "XXXKEYXXX", "BAD DECRYPT");
800       }
801     }
802     WaarpStringUtils.replace(builder, "XXXSSLXXX", isSsl()? CHECKED : "");
803     WaarpStringUtils.replace(builder, "XXXADMXXX", isAdminrole()? CHECKED : "");
804     WaarpStringUtils.replace(builder, "XXXISCXXX", isClient()? CHECKED : "");
805     WaarpStringUtils.replace(builder, "XXXISAXXX", isActive()? CHECKED : "");
806     WaarpStringUtils.replace(builder, "XXXISPXXX", isProxified()? CHECKED : "");
807     WaarpStringUtils.replace(builder, "XXXVERSIONXXX",
808                              COMMA.matcher(getVersion(getHostid()))
809                                   .replaceAll(Matcher.quoteReplacement(", ")));
810     int nb;
811     try {
812       nb = NetworkTransaction.nbAttachedConnection(getSocketAddress(),
813                                                    getHostid());
814     } catch (final Exception e) {
815       nb = -1;
816     }
817     WaarpStringUtils.replace(builder, "XXXCONNXXX",
818                              nb > 0? "(" + nb + " Connected) " : "");
819     return builder.toString();
820   }
821 
822   
823 
824 
825   public static boolean hasProxifiedHosts() {
826     final List<Filter> filters = new ArrayList<Filter>();
827     filters.add(new Filter(DBHostDAO.IS_PROXIFIED_FIELD, "=", true));
828 
829     HostDAO hostAccess = null;
830     try {
831       hostAccess = DAOFactory.getInstance().getHostDAO(false);
832       return hostAccess.count(filters) > 0;
833     } catch (final DAOConnectionException e) {
834       logger.error("DAO Access error", e);
835       return false;
836     } finally {
837       DAOFactory.closeDAO(hostAccess);
838     }
839   }
840 }