From 453bb0b2b2c4eaf20de59844217e00024ce077bb Mon Sep 17 00:00:00 2001 From: Manos Pitsidianakis Date: Mon, 30 Nov 2020 03:25:57 +0200 Subject: melib/smtp: implement gmail XOAUTH2 authentication method --- docs/meli.conf.5 | 20 +++++++++++++++++++- melib/src/smtp.rs | 44 +++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 62 insertions(+), 2 deletions(-) diff --git a/docs/meli.conf.5 b/docs/meli.conf.5 index 2da732f5..f6325c90 100644 --- a/docs/meli.conf.5 +++ b/docs/meli.conf.5 @@ -1132,7 +1132,7 @@ subsection .El .Ss SmtpAuth .Bl -tag -width 36n -.It Ic type Ar "none" | "auto" +.It Ic type Ar "none" | "auto" | "xoauth2" .El .Pp For type "auto": @@ -1146,6 +1146,17 @@ require authentication in every case .Pq Em true .El .sp +For type "xoauth2": +.Bl -tag -width 36n +.It Ic token_command Ar String +Command to evaluate that returns an XOAUTH2 token. +.It Ic require_auth Ar bool +.Pq Em optional +require authentication in every case +.\" default value +.Pq Em true +.El +.sp Examples: .Bd -literal auth = { type = "auto", username = "user", password = { type = "raw", value = "hunter2" } } @@ -1156,6 +1167,13 @@ auth = { type = "auto", username = "user", password = "hunter2" } .Bd -literal auth = { type = "none" } .Ed +.sp +For Gmail (see +.Sx Gmail OAUTH2 +for details on the authentication token command): +.Bd -literal +auth = { type = "xoauth2", token_command = "TOKEN=$(python3 oauth2.py --user=xxx@gmail.com --quiet --client_id=1038[...].apps.googleusercontent.com --client_secret=[..] --refresh_token=[..] && python3 oauth2.py --user=xxx@gmail.com --generate_oauth2_string --quiet --access_token=$TOKEN" } +.Ed .Ss SmtpPassword .Bl -tag -width 36n .It Ic type Ar "raw" | "command_evaluation" diff --git a/melib/src/smtp.rs b/melib/src/smtp.rs index 6c14e63c..5246a440 100644 --- a/melib/src/smtp.rs +++ b/melib/src/smtp.rs @@ -140,6 +140,12 @@ pub enum SmtpAuth { #[serde(skip_serializing, skip_deserializing, default)] auth_type: SmtpAuthType, }, + #[serde(alias = "xoauth2")] + XOAuth2 { + token_command: String, + #[serde(default = "true_val")] + require_auth: bool, + }, // md5, sasl, etc } @@ -162,7 +168,7 @@ impl SmtpAuth { use SmtpAuth::*; match self { None => false, - Auto { require_auth, .. } => *require_auth, + Auto { require_auth, .. } | XOAuth2 { require_auth, .. } => *require_auth, } } } @@ -505,6 +511,39 @@ impl SmtpConnection { .chain_err_kind(crate::error::ErrorKind::Authentication)?; ret.send_command(&[b"EHLO meli.delivery"]).await?; } + SmtpAuth::XOAuth2 { token_command, .. } => { + let password_token = { + let _token_command = token_command.clone(); + let mut output = unblock(move || { + Command::new("sh") + .args(&["-c", &_token_command]) + .stdin(std::process::Stdio::piped()) + .stdout(std::process::Stdio::piped()) + .stderr(std::process::Stdio::piped()) + .output() + }) + .await?; + if !output.status.success() { + return Err(MeliError::new(format!( + "SMTP XOAUTH2 token evaluation command `{}` returned {}: {}", + &token_command, + output.status, + String::from_utf8_lossy(&output.stderr) + ))); + } + if output.stdout.ends_with(b"\n") { + output.stdout.pop(); + } + output.stdout + }; + // https://developers.google.com/gmail/imap/xoauth2-protocol#smtp_protocol_exchange + ret.send_command(&[b"AUTH XOAUTH2 ", &password_token]) + .await?; + ret.read_lines(&mut res, Some((ReplyCode::_235, &[]))) + .await + .chain_err_kind(crate::error::ErrorKind::Authentication)?; + ret.send_command(&[b"EHLO meli.delivery"]).await?; + } } { let extensions_reply = ret @@ -966,6 +1005,9 @@ async fn read_lines<'r>( } } } + if ret.len() < 3 { + return Err(MeliError::new(format!("Invalid SMTP reply: {}", ret))); + } let code = ReplyCode::try_from(&ret[..3])?; let reply = Reply::new(ret, code); //debug!(&reply); -- cgit v1.2.3 Mirror of https://github.com/nextcloud/newsmatthias
summaryrefslogtreecommitdiffstats
path: root/l10n/de_CH.php
blob: 465570578ad613d35386025855c6ef5da10b34a5 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
<?php $TRANSLATIONS = array(
"Can not add feed: Exists already" => "Feed konnte nicht hinzugefügt werden:  Existiert bereits",
"Can not add folder: Exists already" => "Ordner kann nicht hinzgefügt werden: Existiert bereits",
"by" => "von",
"from" => "von",
"Download" => "Herunterladen",
"Web address" => "Internetadresse",
"Folder" => "Ordner",
"New folder" => "Neues Verzeichnis",
"Folder name" => "Ordnername",
"Create" => "Erstellen",
"Rename" => "Umbenennen",
"Collapse" => "Zuklappen",
"Rename folder" => "Ordner umbenennen",
"Delete folder" => "Ordner löschen",
"Starred" => "Markiert",
"Unread articles" => "Ungelesene Artikel",
"All articles" => "Alle Artikel",
"Settings" => "Einstellungen",
"Import" => "Importieren",
"Export" => "Exportieren",
"Error when importing: file does not contain valid OPML" => "Fehler beim Importieren: Datei enthält kein gültiges OPML",
"Error when importing: file does not contain valid JSON" => "Fehler beim Importieren: Datei enthält kein gültiges JSON"
);