Compare commits

..

No commits in common. "3c972dd34e7bcd32be24a3bb9f869a1f00535b64" and "ef04c8a17a7109ddb2c841deb12d496d5330e519" have entirely different histories.

13 changed files with 35 additions and 247 deletions

View file

@ -1,11 +1,11 @@
# MailAutoConf - a simple, configurable autodiscover service for distributed and self-hosted groupware services. # DAVDiscover - a simple, configurable autodiscover service for distributed and self-hosted groupware services.
## What is MailAutoConf? ## What is DAVDiscover?
MailAutoConf is a self-hosted service which provides IMAP, SMTP, CalDAV, CardDav, etc DAVDiscover is a self-hosted service which provides IMAP, SMTP, CalDAV, CardDav, etc
URLs to authenticated clients for ease in set up on mobile devices and also desktop/laptop computers. URLs to authenticated clients for ease in set up on mobile devices and also desktop/laptop computers.
## What ~~does~~ will MailAutoConf do? ## What ~~does~~ will DAVDiscover do?
MailAutoConf is currently in _very_ early stages, with a _very_ limited set of features. DAVDiscover is currently in _very_ early stages, with a _very_ limited set of features.
My hope for MailAutoConf is to mimic the AutoDiscover service found in Microsoft Exchange services, My hope for DAVDiscover is to mimic the AutoDiscover service found in Microsoft Exchange services,
but with the intent of providing a set of URLS for each service which may be self-hosted and/or distributed, but with the intent of providing a set of URLS for each service which may be self-hosted and/or distributed,
primary IMAP, SMTP, CalDAV and CardDAV URLS, but hopefully more services can be added in the future. primary IMAP, SMTP, CalDAV and CardDAV URLS, but hopefully more services can be added in the future.
@ -15,7 +15,7 @@ Getting a set up like this configured on a mobile device is fairly involved for
There are many points where set up configuration mistakes can happen, leading to service outage for a user, and the difficult job of There are many points where set up configuration mistakes can happen, leading to service outage for a user, and the difficult job of
the IT consultant trying to talk the user through setting the device up over the phone. the IT consultant trying to talk the user through setting the device up over the phone.
MailAutoConf intends to patch this problem by providing the URLs and information (Port numbers, SSL/TLS type, domain name, etc.) for each service DAVDiscover intends to patch this problem by providing the URLS and information (Port numbers, SSL/TLS type, domain name, etc.) for each service
in JSON format allowing for the connecting device to automatically set up this information on the device. in JSON format allowing for the connecting device to automatically set up this information on the device.
## What problems do I expect? ## What problems do I expect?
@ -27,13 +27,13 @@ In the perfect world, this service starts to look so fantastic that mobile devic
in their own code as an Account Type (i.e. ActiveSync, Office365, iCloud, IMAP, etc. are all already there), but I'm not sure if I see that happening just yet. in their own code as an Account Type (i.e. ActiveSync, Office365, iCloud, IMAP, etc. are all already there), but I'm not sure if I see that happening just yet.
### Another problem is authentication. ### Another problem is authentication.
I'd like all clients to authenticate to the MailAutoConf service, but where do we get that authentication from? I'd like all clients to authenticate to the DAVDiscover service, but where do we get that authentication from?
We could have local accounts on the MailAutoConf server obviously, but I don't think this feels "fluent" enough. Maybe, using the primary IMAP server address, we could do an authentication request and if that succeeds the login is accepted and MailAutoConf information is sent. We could have local accounts on the DAVDiscover server obviously, but I don't think this feels "fluent" enough. Maybe, using the primary IMAP server address, we could do an authentication request and if that succeeds the login is accepted and DAVDiscover information is sent.
### More problems regarding authentication. ### More problems regarding authentication.
As we're intended to be used for self-hosted, distributed services, each service may have different usernames and passwords. As we're intended to be used for self-hosted, distributed services, each service may have different usernames and passwords.
This means there will have to be some sort of manual credential entry for each service. This means there will have to be some sort of manual credential entry for each service.
I am less concerned with this issue as it currently isn't really in the scope of MailAutoConf to handle this - the goal is to provide the core information (URL, Ports, etc.) not the credentials to log in. I of course want to make the experience as helpful as possible though, so I'll deal with any features surrounding this when I can. I am less concerned with this issue as it currently isn't really in the scope of DAVDiscover to handle this - the goal is to provide the core information (URL, Ports, etc.) not the credentials to log in. I of course want to make the experience as helpful as possible though, so I'll deal with any features surrounding this when I can.
## When will it be ready for production? ## When will it be ready for production?
Well, not yet. Well, not yet.

View file

@ -1,9 +1,9 @@
version: '3.3' version: '3.3'
services: services:
mailautoconf: davdiscover:
container_name: mailautoconf container_name: davdiscover
ports: ports:
- '8010:80' - '8010:80'
volumes: volumes:
- './config:/var/www/html/config' - './config:/var/www/html/config'
image: pswilde/mailautoconf image: pswilde/davdiscover

View file

@ -1,11 +0,0 @@
<!DOCTYPE html>
<html lang="en" dir="ltr">
<head>
<meta charset="utf-8">
<title>DAVDiscover Dashboard Example</title>
</head>
<body>
<p>This is to show the basic output of DAVDiscover, displaying the first few URLs</p>
</body>
</html>

View file

@ -1,6 +1,6 @@
#!/usr/bin/env bash #!/usr/bin/env bash
podman run --name mailautoconf \ podman run --name davdiscover \
--rm \ --rm \
-p "8010:80" \ -p "8010:80" \
-v ./config:/var/www/html/config \ -v ./config:/var/www/html/config \
pswilde/mailautoconf pswilde/davdiscover

View file

@ -19,6 +19,9 @@ class Loader {
break; break;
default: default:
$p = $this->get_page_name(); $p = $this->get_page_name();
if (substr($p,0,6) != "/admin") {
header('Content-Type: application/json'); // <-- header declaration
}
if(substr($p,0,1) == "/") { if(substr($p,0,1) == "/") {
Core::$CurrentPage = substr($p,1); Core::$CurrentPage = substr($p,1);
} else { } else {

View file

@ -1,6 +1,5 @@
<?php <?php
class Responder { class Responder {
private $Response;
public function show_response(){ public function show_response(){
// get the response detailed by the url requested // get the response detailed by the url requested
$response = $this->get_response(); $response = $this->get_response();
@ -14,24 +13,8 @@ class Responder {
} }
} }
private function send_response($response){ private function send_response($response){
switch ($response->content_type){
case "json":
header('Content-Type: application/json');
// Send json encoded response // Send json encoded response
echo json_encode($response, true); echo json_encode($response, true);
break;
case "ms-json":
header('Content-Type: application/json');
// Send json encoded response
echo json_encode($response->content, true);
break;
case "xml":
header('Content-Type: application/xml');
include ($response->content);
break;
}
} }
private function get_response(){ private function get_response(){
$resp = false; $resp = false;
@ -42,16 +25,8 @@ class Responder {
case "get/all": case "get/all":
$resp = $this->all_urls(); $resp = $this->all_urls();
break; break;
case "mail/config-v1.1.xml": case "get/select":
$resp = $this->moz_auto_config(); $resp = $this->selection();
break;
case "autodiscover/autodiscover.xml":
case "Autodiscover/Autodiscover.xml":
$resp = $this->ms_autodiscover();
break;
case "autodiscover/autodiscover.json": //?Email=psw%40wilde.cloud&Protocol=Autodiscoverv1&RedirectCount=1"
case "Autodiscover/Autodiscover.json":
$resp = $this->ms_autodiscover_json();
break; break;
case "none": case "none":
case "test": case "test":
@ -65,6 +40,8 @@ class Responder {
return $resp; return $resp;
} }
private function all_urls(){ private function all_urls(){
// This would be the default request from, say, an app.
$response = new Response(); $response = new Response();
// TODO:: Will work out a better message later // TODO:: Will work out a better message later
@ -72,36 +49,23 @@ class Responder {
// Cycle through each service and add to payload // Cycle through each service and add to payload
foreach (Core::$Config["Services"] as $key => $service){ foreach (Core::$Config["Services"] as $key => $service){
$response->content[$key] = $service; $response->payload[$key] = $service;
} }
return $response; return $response;
} }
private function moz_auto_config(){ private function selection(){
$response = new Response(); $response = new Response();
$response->content_type = "xml"; $response->message = "Not Implemented";
$response->content = "public/autoconfig.php"; $uri = Core::full_url();
return $response; $response->payload = parse_url($uri);
}
private function ms_autodiscover(){
$response = new Response();
$response->content_type = "xml";
$response->content = "public/autodiscover.php";
return $response;
}
private function ms_autodiscover_json(){
$response = new Response();
$response->content_type = "ms-json";
$response->content = new MSAutodiscoverJSONResponse();
$response->content->Protocol = "AutodiscoverV1";
$response->content->Url = Core::$Config["BaseURL"] . "/Autodiscover/Autodiscover.xml";
return $response; return $response;
} }
private function dummy_response(){ private function dummy_response(){
// Generate a dummy response for testing // Generate a dummy response for testing
$response = new Response(); $response = new Response();
$response->message = "OK, here's some scrumptious data! Enjoy!"; $response->message = "OK, here's some scrumptious data! Enjoy!";
$response->content = array("data" => array("some_data" => "Ohhhhhmmmm nom nom nom nom nom nom", $response->payload = array("data" => array("some_data" => "Ohhhhhmmmm nom nom nom nom nom nom",
"extra_data" => array("garnish" => "buuuuuuuuuuurp")), "extra_data" => array("garnish" => "buuuuuuuuuuurp")),
"more_data" => "yuuuuuum yum yum yum"); "more_data" => "yuuuuuum yum yum yum");
return $response; return $response;
@ -115,9 +79,8 @@ class Responder {
} }
class Response { class Response {
public $url; public $url;
public $content_type = "json";
public $message; public $message;
public $content = array(); public $payload = array();
public function __construct(){ public function __construct(){
// add requested page to response. I don't know why, but it could helpful for diagnostics at some point // add requested page to response. I don't know why, but it could helpful for diagnostics at some point
$this->url = Core::$CurrentPage; $this->url = Core::$CurrentPage;
@ -129,7 +92,3 @@ class Response {
} }
} }
class MSAutodiscoverJSONResponse {
public $Protocol;
public $Url;
}

View file

@ -1,84 +0,0 @@
<?php
$conf = Core::$Config["Services"];
$data = Core::get_get_data();
$email_provided = false;
$display_name = false;
$emailaddress = false;
if ($data["emailaddress"]) {
$email_address = $data["emailaddress"];
$display_name = $email_address;
$email_provided = true;
} else if ($data["path"]) {
$query = parse_url($data["path"]);
$email_address = explode("=",$query["query"]);
if ($email_address[0] == "emailaddress") {
$email_address = $email[1];
$email_provided = true;
$display_name = $email_address;
}
}
if ($email_provided) {
if(!Core::$Config["RequireAuthDomain"]) {
$email_address = str_ireplace("@".Core::$Config["Domain"],"",$email_address);
} else if (Core::$Config["LogonDomain"]) {
$email_address = str_ireplace(Core::$Config["Domain"],Core::$Config["LogonDomain"],$email_address);
}
}
// The below link has config-v1.1.xml information
// https://wiki.mozilla.org/Thunderbird:Autoconfiguration:ConfigFileFormat
?>
<clientConfig version="1.1">
<emailProvider id="<?php echo Core::$Config["Domain"]?>">
<domain><?php echo Core::$Config["Domain"]?></domain>
<displayName><?php echo $email_provided ? $display_name : "%EMAILADDRESS%" ;?></displayName>
<?php if($conf["InMail"]){
$in = $conf["InMail"]; ?>
<incomingServer type="<?php echo strtolower($in["Type"]);?>">
<hostname><?php echo $in["Server"];?></hostname>
<port><?php echo $in["Port"];?></port>
<socketType><?php echo $in["SocketType"];?></socketType>
<username><?php echo $email_provided ? $email_address : "%EMAILADDRESS%";?></username>
<authentication><?php echo $in["Authentication"];?></authentication>
</incomingServer>
<?php }
if($conf["OutMail"]){
$out = $conf["OutMail"]; ?>
<outgoingServer type="<?php echo strtolower($out["Type"]);?>">
<hostname><?php echo $out["Server"];?></hostname>
<port><?php echo $out["Port"];?></port>
<socketType><?php echo $out["SocketType"];?></socketType>
<username><?php echo $email_provided ? $email_address : "%EMAILADDRESS%";?></username>
<authentication><?php echo $out["Authentication"];?></authentication>
</outgoingServer>
<?php }
if ($conf["AddressBook"]) {
$card = $conf["AddressBook"]; ?>
<addressBook type="<?php echo strtolower($card["Type"]); ?>">
<username><?php echo $email_provided ? $email_address : "%EMAILADDRESS%";?></username>
<authentication><?php echo $card["Authentication"] ? $card["Authentication"] : "http-basic" ;?></authentication>
<serverURL><?php echo $card["Server"];?></serverURL>
</addressBook>
<?php }
if ($conf["Calendar"]){
$cal = $conf["Calendar"] ;?>
<calendar type="<?php echo strtolower($cal["Type"]);?>">
<username><?php echo $email_provided ? $email_address : "%EMAILADDRESS%";?></username>
<authentication><?php echo $card["Authentication"] ? $card["Authentication"] : "http-basic" ;?></authentication>
<serverURL><?php echo $card["Server"];?></serverURL>
</calendar>
<?php }
if ($conf["WebMail"]) {
$wm = $conf["WebMail"]; ?>
<webMail>
<loginPage url="<?php echo $wm["Server"];?>" />
<loginPageInfo url="<?php echo $wm["Server"];?>">
<username><?php echo $email_provided ? $email_address : "%EMAILADDRESS%";?></username>
<usernameField id="<?php echo $wm["UsernameDivID"];?>" name="<?php echo $wm["UsernameDivName"];?>" />
<passwordField name="<?php echo $wm["PasswordDivName"];?>" />
<loginButton id="<?php echo $wm["SubmitButtonID"];?>" name="<?php echo $wm["SubmitButtonName"];?>"/>
</loginPageInfo>
</webMail>
<?php } ?>
</emailProvider>
</clientConfig>

View file

@ -1,55 +0,0 @@
<?php
$conf = Core::$Config["Services"];
//get raw POST data so we can extract the email address
$data = file_get_contents("php://input");
// file_put_contents(Core::root_dir()."/xmltest", $data);
preg_match("/\<EMailAddress\>(.*?)\<\/EMailAddress\>/", $data, $matches);
//print_r($matches);
// Example POST Request (sent from client) :
// <?xml version="1.0" \?\>
// <Autodiscover xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://schemas.microsoft.com/exchange/autodiscover/outlook/requestschema/2006">
// <Request>
// <EMailAddress>psw@wilde.cloud</EMailAddress>
// <AcceptableResponseSchema>http://schemas.microsoft.com/exchange/autodiscover/outlook/responseschema/2006a</AcceptableResponseSchema>
// </Request>
// </Autodiscover>
echo '<?xml version="1.0" encoding="utf-8" ?>';?>
<Autodiscover xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://schemas.microsoft.com/exchange/autodiscover/responseschema/2006">
<Response xmlns="http://schemas.microsoft.com/exchange/autodiscover/outlook/responseschema/2006a">
<Account>
<AccountType>email</AccountType>
<Action>settings</Action>
<?php if ($conf["InMail"]){
$in = $conf["InMail"];?>
<Protocol>
<Type><?php echo $in["Type"];?></Type>
<Server><?php echo $in["Server"];?></Server>
<Port><?php echo $in["Port"];?></Port>
<DomainRequired><?php echo Core::$Config["RequireAuthDomain"] ? "on" : "off";?></DomainRequired>
<LoginName><?php echo $matches[1]; ?></LoginName>
<SPA><?php echo $in["SPA"] ? "on" : "off";?></SPA>
<SSL><?php echo $in["SocketType"] == "SSL" ? "on" : "off";?></SSL>
<AuthRequired><?php echo $in["NoAuthRequired"] ? "off" : "on";?></AuthRequired>
</Protocol>
<?php }
if ($conf["OutMail"]) {
$out = $conf["OutMail"];?>
<Protocol>
<Type><?php echo $out["Type"];?></Type>
<Server><?php echo $out["Server"];?></Server>
<Port><?php echo $out["Port"];?></Port>
<DomainRequired><?php echo Core::$Config["RequireAuthDomain"] ? "on" : "off";?></DomainRequired>
<LoginName><?php echo $matches[1]; ?></LoginName>
<SPA><?php echo $in["SPA"] ? "on" : "off";?></SPA>
<Encryption><?php echo $in["SocketType"];?></Encryption>
<AuthRequired><?php echo $in["NoAuthRequired"] ? "off" : "on";?></AuthRequired>
<UsePOPAuth><?php echo $in["POPAuth"] ? "on" : "off";?></UsePOPAuth>
<SMTPLast><?php echo $in["SMTPLast"] ? "on" : "off";?></SMTPLast>
</Protocol>
<?php } ?>
</Account>
</Response>
</Autodiscover>

View file

@ -1,13 +1,6 @@
; Sample config.ini file. ; Sample config.ini file.
; Copy this file to "config/config.ini" and adjust the settings to your requirements ; Copy this file to "config/config.ini" and adjust the settings to your requirements
; Set the base domain for use with this service
Domain = example.com
LogonDomain = example.local
RequireAuthDomain = false
BaseURL = "https://autoconfig.example.com"
; Admin User configuration ; Admin User configuration
; not in use yet ; not in use yet
;[AdminUser] ;[AdminUser]

View file

@ -1,16 +1,14 @@
[InMail] [InMail]
Type = "IMAP"
Server = "imap.example.com" Server = "imap.example.com"
Protocol = "IMAP"
Port = 993 Port = 993
SocketType = SSL TLS = true
Authentication = password-cleartext
[OutMail] [OutMail]
Type = "SMTP"
Server = "smtp.example.com" Server = "smtp.example.com"
Protocol = "SMTP"
Port = 465 Port = 465
SocketType = SSL TLS = true
Authentication = password-cleartext
[CalDav] [CalDav]
Server = "https://caldav.example.com/etc/etc/" Server = "https://caldav.example.com/etc/etc/"

View file

@ -1 +0,0 @@
<EMailAddress>psw@wilde.cloud</EMailAddress>

View file

@ -1,4 +0,0 @@
#!/usr/bin/env bash
a2enmod rewrite
service apache2 stop
exec apache2-foreground

View file

@ -1,10 +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 \
--entrypoint "/bin/bash" \
php:7.4-apache \
/test-entry.sh