diff --git a/README.MD b/README.MD index eb939ff..169dbad 100644 --- a/README.MD +++ b/README.MD @@ -13,13 +13,13 @@ https://wiki.mozilla.org/Thunderbird:Autoconfiguration:ConfigFileFormat, should be able to auto-configure using this service. ## Installation -The container file includes set up for an apache webserver to run the application. +MailAutoConf runs its own webserver on port 8010. You will need to supply a volume for the configuration file and port forwarding. ``` podman run -dt \ --name mailautoconf \ - -v ./config:/var/www/html/config \ - -p 8010:80 \ + -v ./config:/mailautoconf/config \ + -p 8010:8010 \ pswilde/mailautoconf ``` You will need a reverse proxy server to publish to the outside world and handle SSL encryption. @@ -40,7 +40,7 @@ server { } } ``` -First run will create sample.ini files in the config directory. Copy these to config.ini and services.ini and configure them to your needs. +First run will create sample.yaml files in the config directory. Copy these to config.yaml and services.yaml and configure them to your needs. MailAutoConf will handle all the URLs it's able to deal with, i.e. /mail/config-v1.1.xml, /Autodiscover/Autodiscover.xml automatically. @@ -63,7 +63,7 @@ MailAutoConf has been tested and confirmed working with the following software p - [x] Nextcloud Mail app - [ ] Other Mail Clients are likely supported if they support /mail/config-v1.1.xml - + ## Future plans MailAutoConf is currently in _very_ early stages, with a _very_ limited set of features. diff --git a/compose.yml b/compose.yml index a0f3bce..d32d0f5 100644 --- a/compose.yml +++ b/compose.yml @@ -3,7 +3,7 @@ services: mailautoconf: container_name: mailautoconf ports: - - '8010:80' + - '8010:8010' volumes: - - './config:/var/www/html/config' + - './config:/mailautoconf/config' image: pswilde/mailautoconf diff --git a/podman-run.sh b/podman-run.sh index a89c52b..98a298b 100644 --- a/podman-run.sh +++ b/podman-run.sh @@ -1,6 +1,6 @@ #!/usr/bin/env bash podman run --name mailautoconf \ --rm \ - -p "8010:80" \ - -v ./config:/var/www/html/config \ + -p "8010:8010" \ + -v ./config:/mailautoconf/config \ pswilde/mailautoconf diff --git a/src/core/db/db.php b/src/core/db/db.php deleted file mode 100644 index 4aaa5b7..0000000 --- a/src/core/db/db.php +++ /dev/null @@ -1,3 +0,0 @@ - diff --git a/src/core/init.php b/src/core/init.php deleted file mode 100644 index 881d98c..0000000 --- a/src/core/init.php +++ /dev/null @@ -1,57 +0,0 @@ -request_page(); - } - private function get_config(){ - // parse the default config file for default values - $default_config = parse_ini_file(Core::root_dir()."/default-config/config.default.ini", true); - // define the custom config file location - $config_file = Core::root_dir()."/config/config.ini"; - $config = array(); - if (file_exists($config_file)) { - // if a custom config file exists then parse that file too - $config = parse_ini_file($config_file, true); - } - // merge the default config with the custom config - Core::$Config = array_merge($default_config,$config); - Core::$Config["PrimaryDomain"] = Core::$Config["Domain"][0]; - - // parse the default services file for default values - $default_services = parse_ini_file(Core::root_dir()."/default-config/services.default.ini", true); - - // define the custom services file location - $services_file = Core::root_dir()."/config/services.ini"; - $services = array(); - if (file_exists($services_file)) { - // if a custom config file exists then parse that file too - $services = parse_ini_file($services_file, true); - } - - // merge the default config with the custom config - // using replace recursive as the config file contains arrays itself - Core::$Config["Services"] = array_replace_recursive($default_services,$services); - - // get the current git commit, if it exists. For testing - Core::$Config["CommitID"] = Core::get_current_git_commit(); - - } -} diff --git a/src/core/init/core.php b/src/core/init/core.php deleted file mode 100644 index 12d204f..0000000 --- a/src/core/init/core.php +++ /dev/null @@ -1,77 +0,0 @@ -$value){ - $data[$key] = $value; - } - return $data; - } - public static function get_get_data(){ - // Gets the GET request into an array - $data = []; - foreach($_GET as $key=>$value){ - $data[$key] = $value; - } - return $data; - } - public static function random_string($length = 10) { - // Generates a random string - unused currently - $characters = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'; - $charactersLength = strlen($characters); - $randomString = ''; - for ($i = 0; $i < $length; $i++) { - $randomString .= $characters[rand(0, $charactersLength - 1)]; - } - return $randomString; - } - public static function start_session(){ - // Starts a session, unused currently - session_start(); - } - public static function end_session($redirect = true){ - // Unset all of the session variables - $_SESSION = array(); - setcookie("user_session", "", time() - 3600); - // Destroy the session. - session_destroy(); - if($redirect){ - header("location: /?e=LogoutSuccess"); - } - } - public static function get_current_git_commit( $branch='master' ) { - // Gets the current git commit ID - for testing - $gitref = sprintf( self::root_dir().'/../.git/refs/heads/%s', $branch ); - if ( file_exists($gitref) && $hash = file_get_contents( $gitref ) ) { - return trim($hash); - } else { - return false; - } - } - public static function full_url(){ - // Gets the full requested URL - if(isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] === 'on') { - $addr = "https"; - } else { - $addr = "http"; - } - // Here append the common URL characters. - $addr .= "://"; - - // Append the host(domain name, ip) to the URL. - $addr .= $_SERVER['HTTP_HOST']; - - // Append the requested resource location to the URL - $addr .= $_SERVER['REQUEST_URI']; - - // Return the address - return $addr; - } -} diff --git a/src/core/init/errors.php b/src/core/init/errors.php deleted file mode 100644 index 472b610..0000000 --- a/src/core/init/errors.php +++ /dev/null @@ -1,34 +0,0 @@ -error = $err; - $this->code = $code; - $this->message = $msg; - $this->url = Core::$CurrentPage; - $this->commit = Core::$Config["CommitID"]; - } -} diff --git a/src/core/init/loader.php b/src/core/init/loader.php deleted file mode 100644 index 09d9dac..0000000 --- a/src/core/init/loader.php +++ /dev/null @@ -1,44 +0,0 @@ -go_to_page(true); - } else { - $this->go_to_page(false); - } - } - public function go_to_page($authenticated) { - switch ($authenticated) { - case false: - require(Core::root_dir()."/public/unauthorized.php"); - break; - default: - $p = $this->get_page_name(); - if(substr($p,0,1) == "/") { - // Remove first slash if exists - Core::$CurrentPage = substr($p,1); - } else { - Core::$CurrentPage = $p; - } - require_once(Core::root_dir()."/public/respond.php"); - break; - } - } - public function get_page_name(){ - $uri = Core::get_get_data(); - $page = "/none"; - if(isset($uri["path"])){ - $page = parse_url($uri["path"]); - $page = $page["path"]; - } - return $page; - } -} diff --git a/src/core/init/responder.php b/src/core/init/responder.php deleted file mode 100644 index ead603c..0000000 --- a/src/core/init/responder.php +++ /dev/null @@ -1,187 +0,0 @@ -get_response(); - if ($response){ - // send response - $this->send_response($response); - } else { - // Send error instead - $e = new Errors(); - $e->throw_error("NotFound"); - } - } - private function send_response($response){ - switch ($response->content_type){ - case "json": - header('Content-Type: application/json'); - // Send json encoded response - echo json_encode($response); - break; - case "ms-json": - header('Content-Type: application/json'); - // Send json encoded response - // This is currently an undocumented file from Microsoft so it's not ready yet - echo json_encode($response->content, JSON_UNESCAPED_UNICODE); - break; - case "xml": - header('Content-Type: application/xml'); - include ($response->content); - break; - } - - - } - private function get_response(){ - $resp = false; - // Handle the requested URL, using as many known autoconfiguration urls as possible - switch (strtolower(Core::$CurrentPage)){ - case "get/test": - $resp = $this->dummy_response(); - break; - case "get/all": - $resp = $this->all_urls(); - break; - case "mail/autoconfig.xml": - case "mail/config-v1.1.xml": - $resp = $this->moz_auto_config(); - break; - case "autodiscover/autodiscover.xml": - $resp = $this->ms_autodiscover(); - break; - case "autodiscover/autodiscover.json": - $resp = $this->ms_autodiscover_json(); - break; - case "get/config": - $resp = $this->get_config(); - break; - case "none": - case "test": - case "home": - case "root": - $resp = $this->get_test_working(); - break; - default: - break; - } - return $resp; - } - private function get_config(){ - $response = new Response(); - $response->message = "Here's your config..."; - foreach (Core::$Config as $k => $v){ - $response->content[$k] = $v; - } - return $response; - } - private function get_username($service,$email_address) { - $username = "%EMAILADDRESS%"; - if(!$service["UsernameIsFQDN"]) { - preg_match("/^[^@]+/",$email_address,$matches); - if (count($matches) > 0){ - $username = $matches[0]; - } - } else if ($service["RequireLogonDomain"]) { - $username = preg_replace("/[^@]+$/",Core::$Config["LogonDomain"],$email_address,1); - } - return $username; - } - private function all_urls(){ - $response = new Response(); - // Not really useful, unless some lovely app developers want to parse it for their app :) - // TODO:: Will work out a better message later - $response->message = "All URLs Requested"; - - // Cycle through each service and add to payload - foreach (Core::$Config["Services"] as $key => $service){ - if (!$service["Enabled"]) { - continue; - } - $response->content[$key] = $service; - } - - return $response; - } - private function moz_auto_config(){ - // The default Thunderbird or Evolution autoconfig.xml file - $response = new Response(); - $response->content_type = "xml"; - $response->content = "public/autoconfig.php"; - return $response; - } - private function ms_autodiscover(){ - // The default Microsoft Autodiscover.xml file - $response = new Response(); - $response->content_type = "xml"; - $response->content = "public/autodiscover.php"; - return $response; - } - private function ms_autodiscover_json(){ - // The new Microsoft Autodiscover.json file - undocumented - $response = new Response(); - $response->content_type = "ms-json"; - if (strtolower($_GET['Protocol']) == 'autodiscoverv1') { - $response->content = new MSAutodiscoverJSONResponse(); - $response->content->Protocol = "AutodiscoverV1"; - $response->content->Url = Core::$Config["BaseURL"] . "/Autodiscover/Autodiscover.xml"; - } else { - $response->content = new MSAutodiscoverJSONError(); - http_response_code(400); - $response->headers_set = true; - $response->content->ErrorCode = "InvalidProtocol"; - $response->content->ErrorMessage = "The given protocol value '" . $_GET['Protocol'] . "' is invalid. Supported values are 'AutodiscoverV1'"; - } - - return $response; - } - private function dummy_response(){ - // Generate a dummy response for testing - $response = new Response(); - $response->message = "OK, here's some scrumptious data! Enjoy!"; - $response->content = array("data" => array("some_data" => "Ohhhhhmmmm nom nom nom nom nom nom", - "extra_data" => array("garnish" => "buuuuuuuuuuurp")), - "more_data" => "yuuuuuum yum yum yum"); - return $response; - } - private function get_test_working(){ - // Generate a dummy response for testing - $response = new Response(); - $response->message = "Success! Things are working! Please request a valid URL i.e. /mail/config-v1.1.xml"; - return $response; - } -} -class Response { - public $url; - public $content_type = "json"; - public $message; - // public $headers_set = false; - public $content = array(); - public function __construct(){ - // add requested page to response. I don't know why, but it could helpful for diagnostics at some point - // Does not happen on autoconfig.xml/autodisocver.xml/autodiscover.json files - $this->url = Core::$CurrentPage; - if (!Core::$Config["CommitID"]){ - $this->version = Core::VERSION; - } else { - $this->version = "git commit ".Core::$Config["CommitID"]; - } - - } -} -class AutoConfig { - public function prepare_autoconfig_info() { - // TODO: Move all the code in autoconfig.php into here - return false; - } -} -class MSAutodiscoverJSONResponse { - // More work to do - handling of MS Autodiscover.json requests - public $Protocol; - public $Url; -} -class MSAutodiscoverJSONError { - public $ErrorCode; - public $ErrorMessage; -} diff --git a/src/core/init/user.php b/src/core/init/user.php deleted file mode 100644 index 5a19619..0000000 --- a/src/core/init/user.php +++ /dev/null @@ -1,9 +0,0 @@ - Authentication -Authentication = password-cleartext - -; Use Secure Password Authentication -SPA = false - -; Change to true if you need the domain/logondomain to form part of the username -UsernameIsFQDN = false - -; Do you need to authenticate to your mail server? You should! so this should be false! -NoAuthRequired = false - -; Use POP Authentication? You probably shouldn't be. -POPAuth = false - -; This setting is here to limit errors, I'm not sure what it does yet. -SMTPLast = false - - -; Currently not implemented, see https://wiki.mozilla.org/Thunderbird:Autoconfiguration:ConfigFileFormat -[Calendar] -; Disable this service -Enabled = false -Server = "https://example.com/remote.php/dav/" -Port = 443 -Type = CalDAV -Authentication = http-basic -UsernameIsFQDN = false - -; Currently not implemented, see https://wiki.mozilla.org/Thunderbird:Autoconfiguration:ConfigFileFormat -[AddressBook] -; Disable this service -Enabled = false -Server = "https://example.com/remote.php/dav/" -Port = 443 -Type = CardDAV -Authentication = http-basic -UsernameIsFQDN = false - -; Currently not implemented, see https://wiki.mozilla.org/Thunderbird:Autoconfiguration:ConfigFileFormat -[WebMail] -; Disable this service -Enabled = false -Server = https://mail.example.com -UsernameDivID = "username" -UsernameDivName = "username" -PasswordDivName = "password" -SubmitButtonID = "submit" -SubmitButtonName = "submit" -UsernameIsFQDN = false - - -; In theory, additional custom services can be configured and will be displayed with -; their options on the /get/all URL of this service. The third-party clients would need to -; check this service as part of their development for this to work -; Will not be shown in autodiscover.xml/json or config-v1.1.xml/autoconfig.xml -; i.e Nextcloud - ideally a nextcloud client could check autoconfig for this URL for ease of set up -;[Nextcloud] -;Server = https://nextcloud.example.com diff --git a/src/index.php b/src/index.php deleted file mode 100644 index 37ad07f..0000000 --- a/src/index.php +++ /dev/null @@ -1,5 +0,0 @@ -start(); diff --git a/src/public/autoconfig.php b/src/public/autoconfig.php deleted file mode 100644 index 767abb2..0000000 --- a/src/public/autoconfig.php +++ /dev/null @@ -1,66 +0,0 @@ - - - "> - - - - %EMAILADDRESS% - - "> - - - - get_username($service,$email_address); ?> - - - - "> - - - - get_username($service,$email_address);?> - - - - "> - get_username($service,$email_address);?> - - - - - "> - get_username($service,$email_address);?> - - - - - - " /> - "> - get_username($service,$email_address);?> - " name="" /> - " /> - " name=""/> - - - - - diff --git a/src/public/autodiscover.php b/src/public/autodiscover.php deleted file mode 100644 index ded1799..0000000 --- a/src/public/autodiscover.php +++ /dev/null @@ -1,52 +0,0 @@ -(.*?)\<\/EMailAddress\>/", $data, $matches); - -// Example POST Request (sent from client) : -// -// -// -// your@email.address -// http://schemas.microsoft.com/exchange/autodiscover/outlook/responseschema/2006a -// -// - -echo '';?> - - - - email - settings - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/public/error.php b/src/public/error.php deleted file mode 100644 index 0478f9d..0000000 --- a/src/public/error.php +++ /dev/null @@ -1,5 +0,0 @@ -throw_error("NotFound"); -exit(); diff --git a/src/public/respond.php b/src/public/respond.php deleted file mode 100644 index 265a9e2..0000000 --- a/src/public/respond.php +++ /dev/null @@ -1,5 +0,0 @@ -show_response(); -exit(); diff --git a/src/public/unauthorized.php b/src/public/unauthorized.php deleted file mode 100644 index c3ea0ce..0000000 --- a/src/public/unauthorized.php +++ /dev/null @@ -1,5 +0,0 @@ -throw_error("Unauthorized"); -exit(); diff --git a/test-entry.sh b/test-entry.sh deleted file mode 100755 index f7d363a..0000000 --- a/test-entry.sh +++ /dev/null @@ -1,4 +0,0 @@ -#!/usr/bin/env bash -a2enmod rewrite -service apache2 stop -exec bash /entrypoint.sh diff --git a/test-server.sh b/test-server.sh deleted file mode 100644 index 46e3087..0000000 --- a/test-server.sh +++ /dev/null @@ -1,11 +0,0 @@ -#!/usr/bin/env bash -podman run --name mailautoconf-test \ - --rm \ - -p "8010:80" \ - -v ./src:/var/www/html/ \ - -v ./config:/var/www/html/config \ - -v ./test-entry.sh:/test-entry.sh \ - -v ./entrypoint.sh:/entrypoint.sh \ - --entrypoint "/bin/bash" \ - php:7.4-apache \ - /test-entry.sh