pax_global_header 0000666 0000000 0000000 00000000064 14045302537 0014515 g ustar 00root root 0000000 0000000 52 comment=ecd1989c827b65b429325df7a1d8dbae84d36197 Modules-ecd1989c827b65b429325df7a1d8dbae84d36197/ 0000775 0000000 0000000 00000000000 14045302537 0020156 5 ustar 00root root 0000000 0000000 Modules-ecd1989c827b65b429325df7a1d8dbae84d36197/README.md 0000664 0000000 0000000 00000004131 14045302537 0021434 0 ustar 00root root 0000000 0000000 This repository is intended for the development of ISPConfig Modules and Add-ons. ------------------------------- - How it works ------------------------------- Each module or addon shall be placed be in a separate directory and contain a README file that explains what this addon does and how it has to be installed. ------------------------------- - License ------------------------------- Add-ons that get developed in this repository shall use a BSD-style license to be compatible with ISPConfig which is licensed under BSD license as well. ------------------------------- - Example License ------------------------------- Copyright (c) DATE, YOUR NAME All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of ISPConfig nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. Modules-ecd1989c827b65b429325df7a1d8dbae84d36197/dns_slave_auto/ 0000775 0000000 0000000 00000000000 14045302537 0023164 5 ustar 00root root 0000000 0000000 Modules-ecd1989c827b65b429325df7a1d8dbae84d36197/dns_slave_auto/README 0000664 0000000 0000000 00000002326 14045302537 0024047 0 ustar 00root root 0000000 0000000 Author: Florian Schaal, schaal @it ISPConfig version: 3.1.3 This addon adds dns-slave-zones on additional servers after creating a dns-zone If you managed multiple servers with ISPConfig but did not use the mirror-function, you can i.e. use server 1 for bind and server 2 as a bind-slave. This plugin manages the slave-zones on server 2 when you create / change / delete the dns-zone on server 1. Installation -------------------- Download the addon to your server and run the install.sh script to install it. Usage -------------------- Adjust the following settings in /usr/local/ispconfig/interface/lib/plugins/dns_dns_slave_auto_plugin.inc.php 1. //* define your dns-ip(s) that the slave-server should accept the data from (same as NS (IP-address) in Secondary DNS Zones) $this->nameservers[] = '192.168.0.1'; $this->nameservers[] = 'fe80::2'; If your master-server has only one IP, remove one one the lines. 2. //* define the server_ids for slave-server(s) (see server_id in dbispconfig.server on the master) $this->dns_slave_server_id[] = 2; If you want to run bind-slave on several servers, use more settings. I.e. $this->dns_slave_server_id[] = 2; $this->dns_slave_server_id[] = 12; $this->dns_slave_server_id[] = 18; Modules-ecd1989c827b65b429325df7a1d8dbae84d36197/dns_slave_auto/dns_dns_slave_auto_plugin.inc.php 0000664 0000000 0000000 00000011121 14045302537 0031671 0 ustar 00root root 0000000 0000000 nameservers[] = '192.168.0.1'; $this->nameservers[] = 'fe80::2'; //* define the server_ids for slave-server(s) (see server_id in dbispconfig.server on the master) $this->dns_slave_server_id[] = 2; } function onLoad() { global $app; $app->plugin->registerEvent('dns:dns_soa:on_after_insert', 'dns_dns_slave_auto_plugin', 'slave_insert'); $app->plugin->registerEvent('dns:dns_soa:on_after_update', 'dns_dns_slave_auto_plugin', 'slave_update'); $app->plugin->registerEvent('dns:dns_soa:on_after_delete', 'dns_dns_slave_auto_plugin', 'slave_delete'); $app->plugin->registerEvent('dns:wizard:on_after_insert', 'dns_dns_slave_auto_plugin', 'slave_insert'); } function slave_insert($event_name, $page_form) { global $app; $soa = $app->db->queryOneRecord("SELECT * FROM dns_soa WHERE id = ?", $page_form->id); $insert_data = array( 'sys_userid' => $soa['sys_userid'], 'sys_groupid' => $soa['sys_groupid'], 'sys_perm_user' => $soa['sys_perm_user'], 'sys_perm_group' => $soa['sys_perm_group'], 'sys_perm_other' => $soa['sys_perm_other'], 'origin' => $soa['origin'], 'ns' => implode(',', $this->nameservers), 'active' => $soa['active'], 'xfer' => '' ); foreach($this->dns_slave_server_id as $slave) { $insert_data['server_id'] = $slave; $app->db->datalogInsert('dns_slave', $insert_data, 'id'); } } function slave_update($event_name, $page_form) { global $app; if($page_form->dataRecord['origin'] != $page_form->oldDataRecord['origin']) { $slave_zone_recs = $app->db->queryAllRecords("SELECT * FROM dns_slave WHERE origin = ?", $page_form->oldDataRecord['origin']); if(!$slave_zone_recs) $this->slave_insert($event_name, $page_form); foreach($slave_zone_recs as $slave_zone) { $app->db->datalogDelete('dns_slave', 'id', $slave_zone['id']); $this->slave_insert($event_name, $page_form); } } if($page_form->dataRecord['active'] != $page_form->oldDataRecord['active']) { $slave_zone_recs = $app->db->queryAllRecords("SELECT * FROM dns_slave WHERE origin = ?", $page_form->dataRecord['origin']); if(!$slave_zone_recs) $this->slave_insert('update_insert', $page_form); foreach($slave_zone_recs as $slave_zone) { if($page_form->dataRecord['active'] == 'Y') { $app->db->datalogUpdate('dns_slave', array('active' => 'Y'), 'id', $slave_zone['id']); } else { $app->db->datalogUpdate('dns_slave', array('active' => 'N'), 'id', $slave_zone['id']); } } } } function slave_delete($event_name, $page_form) { global $app; $slave_zone_recs = $app->db->queryAllRecords("SELECT * FROM dns_slave WHERE origin = ?", $page_form->dataRecord['origin']); foreach($slave_zone_recs as $slave_zone) { $app->db->datalogDelete('dns_slave', 'id', $slave_zone['id']); } } } Modules-ecd1989c827b65b429325df7a1d8dbae84d36197/dns_slave_auto/install.sh 0000775 0000000 0000000 00000000310 14045302537 0025163 0 ustar 00root root 0000000 0000000 #!/bin/bash mv -f dns_dns_slave_auto_plugin.inc.php /usr/local/ispconfig/interface/lib/plugins chown ispconfig:ispconfig /usr/local/ispconfig/interface/lib/plugins/dns_dns_slave_auto_plugin.inc.php Modules-ecd1989c827b65b429325df7a1d8dbae84d36197/ispc_acmeproxy/ 0000775 0000000 0000000 00000000000 14045302537 0023203 5 ustar 00root root 0000000 0000000 Modules-ecd1989c827b65b429325df7a1d8dbae84d36197/ispc_acmeproxy/README.md 0000664 0000000 0000000 00000002740 14045302537 0024465 0 ustar 00root root 0000000 0000000 ### About this module The experimental ispc_acmeproxy module is an attempt to create an environment running alongside an existing ISPConfig installation and uses normal user login credentials to edit DNS TXT records needed for the ACME DNS domain validation. It's primarily made for the [acme.sh](https://github.com/Neilpang/acme.sh) client. The ISPConfig DNS plugin for acme.sh can be used without changes, using user credentials instead of remoting api credentials that cannot be restricted to user resources. Experimental means it works fine for me where I need it, but probably needs more rigorous testing. ### Suggested usage 1. create an ISPC remoting user with proper rights (Client functions, DNS zone functions, DNS txt functions) 2. checkout the repository and copy the ispc_acmeproxy to a convenient place 3. create a new vhost under your web server and point the root to ispc_acmeproxy/web 4. copy ispc_acmeproxy/config/config.inc.php.sample to ispc_acmeproxy/config/config.inc.php and edit accordingly (use credentials from step 1) 5. reload your web server, test using the acme.sh client, etc. You'll need to provide user credentials instead of the API credentials for the DNS plugin as per [the docs](https://github.com/Neilpang/acme.sh/tree/master/dnsapi). ### Etc. See this [forum thread](https://www.howtoforge.com/community/threads/restricting-api-users-to-certain-domains-or-limiting-to-one-clients-resources.80450/) Suggestions, issue reports, PRs are welcome. Modules-ecd1989c827b65b429325df7a1d8dbae84d36197/ispc_acmeproxy/config/ 0000775 0000000 0000000 00000000000 14045302537 0024450 5 ustar 00root root 0000000 0000000 Modules-ecd1989c827b65b429325df7a1d8dbae84d36197/ispc_acmeproxy/config/config.inc.php.sample 0000664 0000000 0000000 00000000305 14045302537 0030454 0 ustar 00root root 0000000 0000000 'https://ispconfig.example.com:8443/remote/json.php', 'apiUsername' => 'remotingUserName', 'apiPassword' => 'remotingUserPass', 'dnsServerId' => 5 ]; Modules-ecd1989c827b65b429325df7a1d8dbae84d36197/ispc_acmeproxy/web/ 0000775 0000000 0000000 00000000000 14045302537 0023760 5 ustar 00root root 0000000 0000000 Modules-ecd1989c827b65b429325df7a1d8dbae84d36197/ispc_acmeproxy/web/acmeproxy.php 0000664 0000000 0000000 00000017656 14045302537 0026517 0 ustar 00root root 0000000 0000000 config = $config; $resp = $this->jsonCall('login', [ 'username' => $config['apiUsername'], 'password' => $config['apiPassword'], 'client_login' => false]); if ($resp->code != 'ok') { throw new RuntimeException('API setup error'); } $this->sessionId = $resp->response; } public function jsonCall($function, $data = null) { if (empty($data)) { $data = new stdClass(); } else { $data = (object)$data; } $data->session_id = $this->sessionId; return jsonRequest("{$this->config['apiUrl']}?$function", $data); } public function initClient($username, $password, $sessionId) { if (!$username && !$sessionId) { throw new InvalidArgumentException("Invalid credentials"); } if ($sessionId) { session_id($sessionId); session_start(); $username = $_SESSION['username']; $password = $_SESSION['password']; } else { session_start(); $sessionId = session_id(); $_SESSION['username'] = $username; $_SESSION['password'] = $password; } $this->client = $this->clientZones = $this->clientZoneNames = null; $this->username = $username; $client = $this->jsonCall('client_get_by_username', ['username' => $username]); if ($client->code != 'ok' || !$this->checkCryptValue($password, $client->response->passwort)) { throw new InvalidArgumentException("Invalid credentials"); } $this->client = $client->response; $clientZones = $this->jsonCall('dns_zone_get_by_user', ['client_id' => $this->client->client_id, 'server_id' => $this->config['dnsServerId']]); $this->clientZones = $clientZones->response; foreach ($this->clientZones as $clientZone) { $this->clientZoneNames[$clientZone->origin] = $clientZone->id; } return $sessionId; } function __destruct() { if ($this->sessionId) { $this->jsonCall('logout'); } } /** * @param $password * @param $saved_password * @return bool */ private static function checkCryptValue($password, $saved_password) { if ($saved_password[0] == '{') { // remove Dovecot-style password prefix (used for email user logins) // example: {MD5-CRYPT}$1$12345678$MfjBLH.L2J1K2v0dXHkeJ/ $saved_password = substr($saved_password, strpos($saved_password, '}') + 1); } if ($saved_password[0] == '$') { // assume prefixed crypt() hash // $saved_password can be used as the salt, as php ignores the part after the last $ character return crypt(stripslashes($password), $saved_password) == $saved_password; } else { // assume MD5 hash return md5(stripslashes($password)) == $saved_password; } } /** * @param $code * @param $message * @param string $data */ private function returnJson($code, $message, $data = '') { $ret = new stdClass; $ret->code = $code; $ret->message = $message; $ret->response = $data; header('Content-Type: application/json; charset="utf-8"'); echo json_encode($ret); } private function proxyCall($method, $data) { $resp = $this->jsonCall($method, $data); $this->returnJson($resp->code, $resp->message, $resp->response); } public function incrementZoneSerial($zoneId) { $soa = $this->jsonCall('dns_zone_get', ['primary_id' => $zoneId])->response; $serial = $soa->serial; $serial_date = intval(substr($serial, 0, 8)); $count = intval(substr($serial, 8, 2)); $current_date = date("Ymd"); if ($serial_date >= $current_date) { $count += 1; if ($count > 99) { $serial_date += 1; $count = 0; } $count = str_pad($count, 2, "0", STR_PAD_LEFT); $new_serial = $serial_date . $count; } else { $new_serial = $current_date . '01'; } $soa->serial = $new_serial; $this->jsonCall('dns_zone_update', ['client_id' => $this->client->client_id, 'primary_id' => $soa->id, 'params' => $soa]); } public function handleJson() { if (!isset($_GET) || !is_array($_GET) || count($_GET) < 1) { $this->returnJson('invalid_method', 'Method not provided in json call'); return; } try { $keys = array_keys($_GET); $method = reset($keys); $raw = file_get_contents("php://input"); $data = json_decode($raw); if (empty($data)) throw new RuntimeException('Invalid JSON data'); switch ($method) { case 'login': $sid = $this->initClient($data->username, $data->password, null); $this->returnJson('ok', '', $sid); break; case 'dns_zone_get': $this->initClient(null, null, $data->session_id); if (!array_key_exists($data->primary_id->origin, $this->clientZoneNames)) { throw new RuntimeException('Permission denied'); } $this->proxyCall($method, $data); break; case 'dns_txt_add': $this->initClient(null, null, $data->session_id); $fulldomain = $data->params->name; $zoneId = -1; foreach ($this->clientZoneNames as $d => $id) { if (endsWith($fulldomain, $d)) { $zoneId = $id; break; } } if ($data->params->server_id != $this->config['dnsServerId'] || $zoneId < 0) { throw new RuntimeException('Permission denied'); } $this->proxyCall($method, $data); $this->incrementZoneSerial($zoneId); break; case 'dns_txt_get': $this->initClient(null, null, $data->session_id); $fulldomain = $data->primary_id->name; $zoneId = -1; foreach ($this->clientZoneNames as $d => $id) { if (endsWith($fulldomain, $d)) { $zoneId = $id; break; } } if ($zoneId < 0) { throw new RuntimeException('Permission denied'); } $this->proxyCall($method, $data); break; case 'dns_txt_delete': $this->initClient(null, null, $data->session_id); $recordId = $data->primary_id; $record = $this->jsonCall('dns_txt_get', ['primary_id' => $recordId])->response; if (empty($record) || array_search($record->zone, $this->clientZoneNames) === false || $record->type != 'TXT') { throw new RuntimeException('Permission denied'); } $this->proxyCall($method, $data); $this->incrementZoneSerial($record->zone); break; } } catch (Exception $e) { $this->returnJson('invalid_data', $e->getMessage()); } } } $acme = new AcmeWrapper($config); $acme->handleJson(); Modules-ecd1989c827b65b429325df7a1d8dbae84d36197/ispc_acmeproxy/web/utils.php 0000664 0000000 0000000 00000003230 14045302537 0025627 0 ustar 00root root 0000000 0000000 array( 'method' => 'POST', 'content' => json_encode($data), 'header' => "Content-Type: application/json\r\n" . "Accept: application/json\r\n" ) ); $context = stream_context_create($request); $result = file_get_contents($url, false, $context); $response = json_decode($result); return $response; } Modules-ecd1989c827b65b429325df7a1d8dbae84d36197/mailbox_import_from_csv/ 0000775 0000000 0000000 00000000000 14045302537 0025101 5 ustar 00root root 0000000 0000000 Modules-ecd1989c827b65b429325df7a1d8dbae84d36197/mailbox_import_from_csv/README 0000664 0000000 0000000 00000001107 14045302537 0025760 0 ustar 00root root 0000000 0000000 Author: Till Brehm, ISPConfig UG https://git.ispconfig.org/u/tbrehm ISPConfig version: 3.2.4 This addon is a CSV style importer for Email accounts. It creates mailboxes based on an account list in CSV format. Email domains get added automatically when they do not exist. Installation -------------------- Download the addon to your server and run the install.sh script to install it. Usage -------------------- The tool installs itself into the tools menu in ISPConfig. An example CSV file that shows the required format for the Mailbox import is part of the addon. Modules-ecd1989c827b65b429325df7a1d8dbae84d36197/mailbox_import_from_csv/install.sh 0000664 0000000 0000000 00000001371 14045302537 0027105 0 ustar 00root root 0000000 0000000 #!/bin/bash mv -f mailbox_import.php /usr/local/ispconfig/interface/web/tools/ mv -f mailbox_import.htm /usr/local/ispconfig/interface/web/tools/templates/ mv -f mailbox_import.menu.php /usr/local/ispconfig/interface/web/tools/lib/menu.d/ chown ispconfig:ispconfig /usr/local/ispconfig/interface/web/tools/mailbox_import.php chown ispconfig:ispconfig /usr/local/ispconfig/interface/web/tools/templates/mailbox_import.htm chown ispconfig:ispconfig /usr/local/ispconfig/interface/web/tools/lib/menu.d/mailbox_import.menu.php chmod 750 /usr/local/ispconfig/interface/web/tools/mailbox_import.php chmod 750 /usr/local/ispconfig/interface/web/tools/templates/mailbox_import.htm chmod 750 /usr/local/ispconfig/interface/web/tools/lib/menu.d/mailbox_import.menu.php Modules-ecd1989c827b65b429325df7a1d8dbae84d36197/mailbox_import_from_csv/mailbox_import.htm 0000664 0000000 0000000 00000004163 14045302537 0030644 0 ustar 00root root 0000000 0000000
Name | Password | Quota | Status | |