package jfconfig; /** * Created : Mar 18, 2012 * * @author pquiring */ import java.io.*; import java.util.*; import javax.swing.*; import javaforce.*; import javaforce.linux.*; public class DNSPanel extends javax.swing.JPanel { /** * Creates new form DNSPanel */ public DNSPanel() { initComponents(); loadZones(); updateZones(); } /** * This method is called from within the constructor to initialize the form. * WARNING: Do NOT modify this code. The content of this method is always * regenerated by the Form Editor. */ @SuppressWarnings("unchecked") // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents private void initComponents() { jToolBar1 = new javax.swing.JToolBar(); back = new javax.swing.JButton(); addZone = new javax.swing.JButton(); editZone = new javax.swing.JButton(); delZone = new javax.swing.JButton(); save = new javax.swing.JButton(); apply = new javax.swing.JButton(); restart = new javax.swing.JButton(); jScrollPane1 = new javax.swing.JScrollPane(); zones = new javax.swing.JList(); jScrollPane2 = new javax.swing.JScrollPane(); entries = new javax.swing.JList(); jToolBar2 = new javax.swing.JToolBar(); addEntry = new javax.swing.JButton(); editEntry = new javax.swing.JButton(); delEntry = new javax.swing.JButton(); up = new javax.swing.JButton(); down = new javax.swing.JButton(); jToolBar1.setFloatable(false); jToolBar1.setRollover(true); back.setText("<Back"); back.setFocusable(false); back.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER); back.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM); back.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { backActionPerformed(evt); } }); jToolBar1.add(back); addZone.setText("Add Zone"); addZone.setFocusable(false); addZone.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER); addZone.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM); addZone.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { addZoneActionPerformed(evt); } }); jToolBar1.add(addZone); editZone.setText("Edit Zone"); editZone.setFocusable(false); editZone.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER); editZone.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM); editZone.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { editZoneActionPerformed(evt); } }); jToolBar1.add(editZone); delZone.setText("Del Zone"); delZone.setFocusable(false); delZone.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER); delZone.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM); delZone.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { delZoneActionPerformed(evt); } }); jToolBar1.add(delZone); save.setText("Save"); save.setFocusable(false); save.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER); save.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM); save.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { saveActionPerformed(evt); } }); jToolBar1.add(save); apply.setText("Apply"); apply.setFocusable(false); apply.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER); apply.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM); apply.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { applyActionPerformed(evt); } }); jToolBar1.add(apply); restart.setText("Restart Server"); restart.setFocusable(false); restart.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER); restart.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM); restart.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { restartActionPerformed(evt); } }); jToolBar1.add(restart); zones.setModel(zonesModel); zones.setSelectionMode(javax.swing.ListSelectionModel.SINGLE_SELECTION); zones.addListSelectionListener(new javax.swing.event.ListSelectionListener() { public void valueChanged(javax.swing.event.ListSelectionEvent evt) { zonesValueChanged(evt); } }); jScrollPane1.setViewportView(zones); entries.setModel(entriesModel); entries.setSelectionMode(javax.swing.ListSelectionModel.SINGLE_SELECTION); jScrollPane2.setViewportView(entries); jToolBar2.setFloatable(false); jToolBar2.setRollover(true); addEntry.setText("Add Entry"); addEntry.setFocusable(false); addEntry.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER); addEntry.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM); addEntry.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { addEntryActionPerformed(evt); } }); jToolBar2.add(addEntry); editEntry.setText("Edit Entry"); editEntry.setFocusable(false); editEntry.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER); editEntry.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM); editEntry.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { editEntryActionPerformed(evt); } }); jToolBar2.add(editEntry); delEntry.setText("Del Entry"); delEntry.setFocusable(false); delEntry.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER); delEntry.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM); delEntry.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { delEntryActionPerformed(evt); } }); jToolBar2.add(delEntry); up.setText("Up"); up.setFocusable(false); up.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER); up.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM); up.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { upActionPerformed(evt); } }); jToolBar2.add(up); down.setText("Down"); down.setFocusable(false); down.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER); down.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM); down.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { downActionPerformed(evt); } }); jToolBar2.add(down); javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this); this.setLayout(layout); layout.setHorizontalGroup( layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addComponent(jToolBar1, javax.swing.GroupLayout.DEFAULT_SIZE, 519, Short.MAX_VALUE) .addComponent(jScrollPane1) .addComponent(jScrollPane2) .addComponent(jToolBar2, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) ); layout.setVerticalGroup( layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(layout.createSequentialGroup() .addComponent(jToolBar1, javax.swing.GroupLayout.PREFERRED_SIZE, 25, javax.swing.GroupLayout.PREFERRED_SIZE) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 206, Short.MAX_VALUE) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addComponent(jToolBar2, javax.swing.GroupLayout.PREFERRED_SIZE, 25, javax.swing.GroupLayout.PREFERRED_SIZE) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addComponent(jScrollPane2, javax.swing.GroupLayout.PREFERRED_SIZE, 238, javax.swing.GroupLayout.PREFERRED_SIZE)) ); }// </editor-fold>//GEN-END:initComponents private void backActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_backActionPerformed ConfigApp.This.setPanel(new ServersPanel()); }//GEN-LAST:event_backActionPerformed private void zonesValueChanged(javax.swing.event.ListSelectionEvent evt) {//GEN-FIRST:event_zonesValueChanged updateEntries(); }//GEN-LAST:event_zonesValueChanged private void addZoneActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_addZoneActionPerformed addZone(); }//GEN-LAST:event_addZoneActionPerformed private void editZoneActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_editZoneActionPerformed int idx = zones.getSelectedIndex(); if (idx == -1) return; editZone(idx); }//GEN-LAST:event_editZoneActionPerformed private void delZoneActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_delZoneActionPerformed int idx = zones.getSelectedIndex(); if (idx == -1) return; delZone(idx); }//GEN-LAST:event_delZoneActionPerformed private void saveActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_saveActionPerformed saveZones(); }//GEN-LAST:event_saveActionPerformed private void applyActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_applyActionPerformed apply(); }//GEN-LAST:event_applyActionPerformed private void restartActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_restartActionPerformed restart(); }//GEN-LAST:event_restartActionPerformed private void addEntryActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_addEntryActionPerformed addEntry(); }//GEN-LAST:event_addEntryActionPerformed private void editEntryActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_editEntryActionPerformed int idx = entries.getSelectedIndex(); if (idx == -1) return; editEntry(idx); }//GEN-LAST:event_editEntryActionPerformed private void delEntryActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_delEntryActionPerformed int idx = entries.getSelectedIndex(); if (idx == -1) return; delEntry(idx); }//GEN-LAST:event_delEntryActionPerformed private void upActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_upActionPerformed int zidx = zones.getSelectedIndex(); if (zidx == -1) return; int eidx = entries.getSelectedIndex(); if (eidx == -1) return; if (eidx == 0) return; Entry tmp = config.zone[zidx].entry[eidx]; config.zone[zidx].entry[eidx] = config.zone[zidx].entry[eidx-1]; config.zone[zidx].entry[eidx-1] = tmp; updateEntries(); }//GEN-LAST:event_upActionPerformed private void downActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_downActionPerformed int zidx = zones.getSelectedIndex(); if (zidx == -1) return; int eidx = entries.getSelectedIndex(); if (eidx == -1) return; if (eidx == config.zone[zidx].entry.length-1) return; Entry tmp = config.zone[zidx].entry[eidx]; config.zone[zidx].entry[eidx] = config.zone[zidx].entry[eidx+1]; config.zone[zidx].entry[eidx+1] = tmp; updateEntries(); }//GEN-LAST:event_downActionPerformed // Variables declaration - do not modify//GEN-BEGIN:variables private javax.swing.JButton addEntry; private javax.swing.JButton addZone; private javax.swing.JButton apply; private javax.swing.JButton back; private javax.swing.JButton delEntry; private javax.swing.JButton delZone; private javax.swing.JButton down; private javax.swing.JButton editEntry; private javax.swing.JButton editZone; private javax.swing.JList entries; private javax.swing.JScrollPane jScrollPane1; private javax.swing.JScrollPane jScrollPane2; private javax.swing.JToolBar jToolBar1; private javax.swing.JToolBar jToolBar2; private javax.swing.JButton restart; private javax.swing.JButton save; private javax.swing.JButton up; private javax.swing.JList zones; // End of variables declaration//GEN-END:variables public static class Entry { public String name, type, metric, value; //metric is used the MX records } public static class Zone { public Zone() { entry = new Entry[0]; } public boolean master; public String others; //if master==true others=secdonary servers else others=master public String name; //example.com public Entry entry[]; public int ttl; //in seconds } public static class Config { public Zone zone[]; } private DefaultListModel zonesModel = new DefaultListModel(); private DefaultListModel entriesModel = new DefaultListModel(); private Config config; private String configFolder = "/etc/jconfig.d/"; private String configFile = "dns.xml"; private void loadZones() { defaultConfig(); try { XML xml = new XML(); FileInputStream fis = new FileInputStream(configFolder + configFile); xml.read(fis); xml.writeClass(config); } catch (FileNotFoundException e1) { defaultConfig(); } catch (Exception e2) { JFLog.log(e2); defaultConfig(); } } private void defaultConfig() { config = new Config(); config.zone = new Zone[0]; } private void saveZones() { try { XML xml = new XML(); File tmpFile = File.createTempFile("dns", ".xml"); FileOutputStream fos = new FileOutputStream(tmpFile); xml.readClass("dns", config); xml.write(fos); fos.close(); Linux.mkdir(configFolder); if (!Linux.copyFile(tmpFile.getAbsolutePath(), configFolder + configFile)) { tmpFile.delete(); throw new Exception("file io error"); } tmpFile.delete(); } catch (Exception e) { JFLog.log(e); } } private String getZoneString(Zone zone) { return zone.name; } private void updateZones() { zonesModel.clear(); for(int a=0;a<config.zone.length;a++) { zonesModel.addElement(getZoneString(config.zone[a])); } } private String getEntryString(Entry entry) { if (entry.type.equals("MX")) { return entry.name + "(" + entry.type + ")=" + entry.metric + " " + entry.value; } else { return entry.name + "(" + entry.type + ")=" + entry.value; } } private void updateEntries() { entriesModel.clear(); int idx = zones.getSelectedIndex(); if (idx == -1) return; Zone zone = config.zone[idx]; for(int a=0;a<zone.entry.length;a++) { entriesModel.addElement(getEntryString(zone.entry[a])); } } private void restart() { if (Linux.restartService("bind9")) JF.showMessage("Notice", "DNS Service Restarted"); else JF.showError("Error", "Failed to Restart DNS Service"); } private void addZone() { DNSZoneDialog dialog = new DNSZoneDialog(ConfigApp.This, true, null); dialog.setVisible(true); if (!dialog.accepted) return; Zone newZone = new Zone(); newZone.name = dialog.getName(); newZone.master = dialog.getMaster(); newZone.others = dialog.getOthers(); newZone.ttl = dialog.getTTL(); config.zone = Arrays.copyOf(config.zone, config.zone.length + 1); config.zone[config.zone.length-1] = newZone; updateZones(); } private void editZone(int idx) { Zone zone = config.zone[idx]; DNSZoneDialog dialog = new DNSZoneDialog(ConfigApp.This, true, zone); dialog.setVisible(true); if (!dialog.accepted) return; zone.name = dialog.getName(); zone.master = dialog.getMaster(); zone.others = dialog.getOthers(); zone.ttl = dialog.getTTL(); updateZones(); } private void delZone(int idx) { Zone zone = config.zone[idx]; if (!JF.showConfirm("Confirm", "Are you sure you want to delete '" + zone.name + "'?")) return; int len = config.zone.length; Zone newList[] = new Zone[len-1]; System.arraycopy(config.zone, 0, newList, 0, idx); System.arraycopy(config.zone, idx+1, newList, idx, len - idx - 1); config.zone = newList; updateZones(); } private void addEntry() { int zidx = zones.getSelectedIndex(); if (zidx == -1) return; DNSEntryDialog dialog = new DNSEntryDialog(ConfigApp.This, true, null); dialog.setVisible(true); if (!dialog.accepted) return; Entry newEntry = new Entry(); newEntry.name = dialog.getName(); newEntry.type = dialog.getDNSType(); newEntry.metric = dialog.getMetric(); newEntry.value = dialog.getValue(); config.zone[zidx].entry = Arrays.copyOf(config.zone[zidx].entry, config.zone[zidx].entry.length + 1); config.zone[zidx].entry[config.zone[zidx].entry.length-1] = newEntry; updateEntries(); } private void editEntry(int idx) { int zidx = zones.getSelectedIndex(); if (zidx == -1) return; Entry entry = config.zone[zidx].entry[idx]; DNSEntryDialog dialog = new DNSEntryDialog(ConfigApp.This, true, entry); dialog.setVisible(true); if (!dialog.accepted) return; entry.name = dialog.getName(); entry.type = dialog.getDNSType(); entry.metric = dialog.getMetric(); entry.value = dialog.getValue(); updateEntries(); } private void delEntry(int idx) { int zidx = zones.getSelectedIndex(); if (zidx == -1) return; Entry entry = config.zone[zidx].entry[idx]; if (!JF.showConfirm("Confirm", "Are you sure you want to delete '" + entry.name + "'?")) return; int len = config.zone[zidx].entry.length; Entry newList[] = new Entry[len-1]; System.arraycopy(config.zone[zidx].entry, 0, newList, 0, idx); System.arraycopy(config.zone[zidx].entry, idx+1, newList, idx, len - idx - 1); config.zone[zidx].entry = newList; updateZones(); } private void applyEntry(Entry entry, OutputStream os) throws Exception { StringBuilder str = new StringBuilder(); str.append(entry.name); str.append(" IN "); str.append(entry.type); str.append(" "); if (entry.type.equals("MX")) { str.append(entry.metric); str.append(" "); } str.append(entry.value); str.append("\n"); os.write(str.toString().getBytes()); } private void applyZone(Zone zone, OutputStream os) throws Exception { StringBuilder str = new StringBuilder(); File tmpFile = File.createTempFile("zoneFile", ""); FileOutputStream fos = new FileOutputStream(tmpFile); fos.write(("$TTL " + zone.ttl + "\n").getBytes()); fos.write(("$ORIGIN " + zone.name + ".\n").getBytes()); fos.write(("@ " + zone.ttl + " IN SOA ns1." + zone.name + ". admin." + zone.name + ". (2002022401 3H 15 1w 3h)\n").getBytes()); for(int a=0;a<zone.entry.length;a++) { applyEntry(zone.entry[a], fos); } fos.close(); if (!Linux.copyFile(tmpFile.getAbsolutePath(), "/var/cache/bind/" + zone.name)) throw new Exception("file copy error"); tmpFile.delete(); str.append("zone \"" + zone.name + "\" in{\n"); str.append(" type " + (zone.master ? "master" : "slave") + ";\n"); str.append(" file \"" + zone.name + "\";\n"); if (zone.master) { if (zone.others.length() > 0) { str.append(" allow-transfer {"); String others[] = zone.others.split(" "); for(int a=0;a<others.length;a++) { str.append(others[a]); str.append(";"); } str.append("};\n"); } } else { if (zone.others.length() > 0) { str.append(" masters {"); String others[] = zone.others.split(" "); for(int a=0;a<others.length;a++) { str.append(others[a]); str.append(";"); } str.append("};\n"); } } str.append("};\n"); //JFLog.log("str="+str.toString()); os.write(str.toString().getBytes()); } private void apply() { //save config to /etc/bind/named.conf.local try { File tmpFile = File.createTempFile("dns", ".conf"); FileOutputStream fos = new FileOutputStream(tmpFile); for(int a=0;a<config.zone.length;a++) applyZone(config.zone[a], fos); fos.close(); //copy tmpFile to /etc/bind/named.conf.local if (!Linux.copyFile(tmpFile.getAbsolutePath(), "/etc/bind/named.conf.local")) throw new Exception("file copy error"); JF.showMessage("Notice", "Settings have been applied, please restart server."); } catch (Exception e) { JFLog.log(e); JF.showError("Error", "Failed to apply settings."); } } }