You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

133 lines
4.5 KiB

  1. /*
  2. * meli - managesieve
  3. *
  4. * Copyright 2020 Manos Pitsidianakis
  5. *
  6. * This file is part of meli.
  7. *
  8. * meli is free software: you can redistribute it and/or modify
  9. * it under the terms of the GNU General Public License as published by
  10. * the Free Software Foundation, either version 3 of the License, or
  11. * (at your option) any later version.
  12. *
  13. * meli is distributed in the hope that it will be useful,
  14. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  16. * GNU General Public License for more details.
  17. *
  18. * You should have received a copy of the GNU General Public License
  19. * along with meli. If not, see <http://www.gnu.org/licenses/>.
  20. */
  21. use super::{ImapConnection, ImapProtocol, ImapServerConf, UIDStore};
  22. use crate::conf::AccountSettings;
  23. use crate::error::{MeliError, Result};
  24. use crate::get_conf_val;
  25. use nom::IResult;
  26. use std::str::FromStr;
  27. use std::sync::{Arc, Mutex};
  28. use std::time::Instant;
  29. named!(
  30. pub managesieve_capabilities<Vec<(&[u8], &[u8])>>,
  31. do_parse!(
  32. ret: separated_nonempty_list_complete!(tag!(b"\r\n"), alt_complete!(separated_pair!(quoted_raw, tag!(b" "), quoted_raw) | map!(quoted_raw, |q| (q, &b""[..]))))
  33. >> opt!(tag!("\r\n"))
  34. >> ({ ret })
  35. )
  36. );
  37. #[test]
  38. fn test_managesieve_capabilities() {
  39. assert_eq!(managesieve_capabilities(b"\"IMPLEMENTATION\" \"Dovecot Pigeonhole\"\r\n\"SIEVE\" \"fileinto reject envelope encoded-character vacation subaddress comparator-i;ascii-numeric relational regex imap4flags copy include variables body enotify environment mailbox date index ihave duplicate mime foreverypart extracttext\"\r\n\"NOTIFY\" \"mailto\"\r\n\"SASL\" \"PLAIN\"\r\n\"STARTTLS\"\r\n\"VERSION\" \"1.0\"\r\n").to_full_result(), Ok(vec![
  40. (&b"IMPLEMENTATION"[..],&b"Dovecot Pigeonhole"[..]),
  41. (&b"SIEVE"[..],&b"fileinto reject envelope encoded-character vacation subaddress comparator-i;ascii-numeric relational regex imap4flags copy include variables body enotify environment mailbox date index ihave duplicate mime foreverypart extracttext"[..]),
  42. (&b"NOTIFY"[..],&b"mailto"[..]),
  43. (&b"SASL"[..],&b"PLAIN"[..]),
  44. (&b"STARTTLS"[..], &b""[..]),
  45. (&b"VERSION"[..],&b"1.0"[..])])
  46. );
  47. }
  48. // Return a byte sequence surrounded by "s and decoded if necessary
  49. pub fn quoted_raw(input: &[u8]) -> IResult<&[u8], &[u8]> {
  50. if input.is_empty() || input[0] != b'"' {
  51. return IResult::Error(nom::ErrorKind::Custom(0));
  52. }
  53. let mut i = 1;
  54. while i < input.len() {
  55. if input[i] == b'\"' && input[i - 1] != b'\\' {
  56. return IResult::Done(&input[i + 1..], &input[1..i]);
  57. }
  58. i += 1;
  59. }
  60. return IResult::Error(nom::ErrorKind::Custom(0));
  61. }
  62. pub trait ManageSieve {
  63. fn havespace(&mut self) -> Result<()>;
  64. fn putscript(&mut self) -> Result<()>;
  65. fn listscripts(&mut self) -> Result<()>;
  66. fn setactive(&mut self) -> Result<()>;
  67. fn getscript(&mut self) -> Result<()>;
  68. fn deletescript(&mut self) -> Result<()>;
  69. fn renamescript(&mut self) -> Result<()>;
  70. }
  71. pub fn new_managesieve_connection(s: &AccountSettings) -> Result<ImapConnection> {
  72. let server_hostname = get_conf_val!(s["server_hostname"])?;
  73. let server_username = get_conf_val!(s["server_username"])?;
  74. let server_password = get_conf_val!(s["server_password"])?;
  75. let server_port = get_conf_val!(s["server_port"], 4190)?;
  76. let danger_accept_invalid_certs: bool = get_conf_val!(s["danger_accept_invalid_certs"], false)?;
  77. let server_conf = ImapServerConf {
  78. server_hostname: server_hostname.to_string(),
  79. server_username: server_username.to_string(),
  80. server_password: server_password.to_string(),
  81. server_port,
  82. use_starttls: true,
  83. danger_accept_invalid_certs,
  84. protocol: ImapProtocol::ManageSieve,
  85. };
  86. let uid_store = Arc::new(UIDStore {
  87. is_online: Arc::new(Mutex::new((
  88. Instant::now(),
  89. Err(MeliError::new("Account is uninitialised.")),
  90. ))),
  91. ..Default::default()
  92. });
  93. Ok(ImapConnection::new_connection(&server_conf, uid_store))
  94. }
  95. impl ManageSieve for ImapConnection {
  96. fn havespace(&mut self) -> Result<()> {
  97. Ok(())
  98. }
  99. fn putscript(&mut self) -> Result<()> {
  100. Ok(())
  101. }
  102. fn listscripts(&mut self) -> Result<()> {
  103. Ok(())
  104. }
  105. fn setactive(&mut self) -> Result<()> {
  106. Ok(())
  107. }
  108. fn getscript(&mut self) -> Result<()> {
  109. Ok(())
  110. }
  111. fn deletescript(&mut self) -> Result<()> {
  112. Ok(())
  113. }
  114. fn renamescript(&mut self) -> Result<()> {
  115. Ok(())
  116. }
  117. }