NeoMutt  2021-02-05-666-ge300cd
Teaching an old dog new tricks
DOXYGEN

Note about ssf: in actuality, NeoMutt uses this as a boolean to determine if the connection is "secure" using TLS or $tunnel if $tunnel_is_secure is set. More...

+ Collaboration diagram for open():

Functions

static int tls_socket_open (struct Connection *conn)
 Open a TLS socket - Implements Connection::open() -. More...
 
static int ssl_socket_open_err (struct Connection *conn)
 Error callback for opening an SSL connection - Implements Connection::open() -. More...
 
static int ssl_socket_open (struct Connection *conn)
 Open an SSL socket - Implements Connection::open() -. More...
 
int raw_socket_open (struct Connection *conn)
 Open a socket - Implements Connection::open() -. More...
 
static int mutt_sasl_conn_open (struct Connection *conn)
 empty wrapper for underlying open function - Implements Connection::open() -We don't know in advance that a connection will use SASL, so we replace conn's methods with sasl methods when authentication is successful, using mutt_sasl_setup_conn More...
 
static int tunnel_socket_open (struct Connection *conn)
 Open a tunnel socket - Implements Connection::open() -. More...
 
static int zstrm_open (struct Connection *conn)
 Open a socket - Implements Connection::open() -. More...
 

Variables

int(* SaslSockData::open )(struct Connection *conn)
 Open a socket Connection - Implements Connection::open() -. More...
 

Detailed Description

Note about ssf: in actuality, NeoMutt uses this as a boolean to determine if the connection is "secure" using TLS or $tunnel if $tunnel_is_secure is set.

The value is passed to SASL, but since no min_ssf is also passed to SASL I don't believe it makes any difference.

The GnuTLS code currently even puts bytes in here, so I doubt the exact value has significance for NeoMutt purposes.

Open a socket Connection

Parameters
connConnection to a server
Return values
0Success
-1Error

Function Documentation

◆ tls_socket_open()

static int tls_socket_open ( struct Connection conn)
static

Open a TLS socket - Implements Connection::open() -.

Definition at line 1050 of file gnutls.c.

1051 {
1052  if (raw_socket_open(conn) < 0)
1053  return -1;
1054 
1055  if (tls_negotiate(conn) < 0)
1056  {
1057  tls_socket_close(conn);
1058  return -1;
1059  }
1060 
1061  return 0;
1062 }
static int tls_negotiate(struct Connection *conn)
Negotiate TLS connection.
Definition: gnutls.c:890
static int tls_socket_close(struct Connection *conn)
Close a TLS socket - Implements Connection::close() -.
Definition: gnutls.c:1025
int raw_socket_open(struct Connection *conn)
Open a socket - Implements Connection::open() -.
Definition: raw.c:120
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ ssl_socket_open_err()

static int ssl_socket_open_err ( struct Connection conn)
static

Error callback for opening an SSL connection - Implements Connection::open() -.

Return values
-1Always

Definition at line 355 of file openssl.c.

356 {
357  mutt_error(_("SSL disabled due to the lack of entropy"));
358  return -1;
359 }
#define mutt_error(...)
Definition: logging.h:88
#define _(a)
Definition: message.h:28
+ Here is the caller graph for this function:

◆ ssl_socket_open()

static int ssl_socket_open ( struct Connection conn)
static

Open an SSL socket - Implements Connection::open() -.

Definition at line 1332 of file openssl.c.

1333 {
1334  if (raw_socket_open(conn) < 0)
1335  return -1;
1336 
1337  int rc = ssl_setup(conn);
1338  if (rc)
1339  raw_socket_close(conn);
1340 
1341  return rc;
1342 }
static int ssl_setup(struct Connection *conn)
Set up SSL on the Connection.
Definition: openssl.c:1209
int raw_socket_open(struct Connection *conn)
Open a socket - Implements Connection::open() -.
Definition: raw.c:120
int raw_socket_close(struct Connection *conn)
Close a socket - Implements Connection::close() -.
Definition: raw.c:365
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ raw_socket_open()

int raw_socket_open ( struct Connection conn)

Open a socket - Implements Connection::open() -.

Definition at line 120 of file raw.c.

121 {
122  int rc;
123 
124  char *host_idna = NULL;
125 
126 #ifdef HAVE_GETADDRINFO
127  /* --- IPv4/6 --- */
128 
129  /* "65536\0" */
130  char port[6];
131  struct addrinfo hints;
132  struct addrinfo *res = NULL;
133  struct addrinfo *cur = NULL;
134 
135  /* we accept v4 or v6 STREAM sockets */
136  memset(&hints, 0, sizeof(hints));
137 
138  const bool c_use_ipv6 = cs_subset_bool(NeoMutt->sub, "use_ipv6");
139  if (c_use_ipv6)
140  hints.ai_family = AF_UNSPEC;
141  else
142  hints.ai_family = AF_INET;
143 
144  hints.ai_socktype = SOCK_STREAM;
145 
146  snprintf(port, sizeof(port), "%d", conn->account.port);
147 
148 #ifdef HAVE_LIBIDN
149  if (mutt_idna_to_ascii_lz(conn->account.host, &host_idna, 1) != 0)
150  {
151  mutt_error(_("Bad IDN: '%s'"), conn->account.host);
152  return -1;
153  }
154 #else
155  host_idna = conn->account.host;
156 #endif
157 
158  if (!OptNoCurses)
159  mutt_message(_("Looking up %s..."), conn->account.host);
160 
161  rc = getaddrinfo(host_idna, port, &hints, &res);
162 
163 #ifdef HAVE_LIBIDN
164  FREE(&host_idna);
165 #endif
166 
167  if (rc)
168  {
169  mutt_error(_("Could not find the host \"%s\""), conn->account.host);
170  return -1;
171  }
172 
173  if (!OptNoCurses)
174  mutt_message(_("Connecting to %s..."), conn->account.host);
175 
176  rc = -1;
177  for (cur = res; cur; cur = cur->ai_next)
178  {
179  int fd = socket(cur->ai_family, cur->ai_socktype, cur->ai_protocol);
180  if (fd >= 0)
181  {
182  rc = socket_connect(fd, cur->ai_addr);
183  if (rc == 0)
184  {
185  fcntl(fd, F_SETFD, FD_CLOEXEC);
186  conn->fd = fd;
187  break;
188  }
189  else
190  close(fd);
191  }
192  }
193 
194  freeaddrinfo(res);
195 #else
196  /* --- IPv4 only --- */
197 
198  struct sockaddr_in sin;
199  struct hostent *he = NULL;
200 
201  memset(&sin, 0, sizeof(sin));
202  sin.sin_port = htons(conn->account.port);
203  sin.sin_family = AF_INET;
204 
205 #ifdef HAVE_LIBIDN
206  if (mutt_idna_to_ascii_lz(conn->account.host, &host_idna, 1) != 0)
207  {
208  mutt_error(_("Bad IDN: '%s'"), conn->account.host);
209  return -1;
210  }
211 #else
212  host_idna = conn->account.host;
213 #endif
214 
215  if (!OptNoCurses)
216  mutt_message(_("Looking up %s..."), conn->account.host);
217 
218  he = gethostbyname(host_idna);
219 
220 #ifdef HAVE_LIBIDN
221  FREE(&host_idna);
222 #endif
223 
224  if (!he)
225  {
226  mutt_error(_("Could not find the host \"%s\""), conn->account.host);
227 
228  return -1;
229  }
230 
231  if (!OptNoCurses)
232  mutt_message(_("Connecting to %s..."), conn->account.host);
233 
234  rc = -1;
235  for (int i = 0; he->h_addr_list[i]; i++)
236  {
237  memcpy(&sin.sin_addr, he->h_addr_list[i], he->h_length);
238  int fd = socket(PF_INET, SOCK_STREAM, IPPROTO_IP);
239 
240  if (fd >= 0)
241  {
242  rc = socket_connect(fd, (struct sockaddr *) &sin);
243  if (rc == 0)
244  {
245  fcntl(fd, F_SETFD, FD_CLOEXEC);
246  conn->fd = fd;
247  break;
248  }
249  else
250  close(fd);
251  }
252  }
253 #endif
254  if (rc)
255  {
256  mutt_error(_("Could not connect to %s (%s)"), conn->account.host,
257  (rc > 0) ? strerror(rc) : _("unknown error"));
258  return -1;
259  }
260 
261  return 0;
262 }
bool cs_subset_bool(const struct ConfigSubset *sub, const char *name)
Get a boolean config item by name.
Definition: helpers.c:73
struct ConnAccount account
Account details: username, password, etc.
Definition: connection.h:40
#define mutt_error(...)
Definition: logging.h:88
#define _(a)
Definition: message.h:28
WHERE bool OptNoCurses
(pseudo) when sending in batch mode
Definition: options.h:47
Container for Accounts, Notifications.
Definition: neomutt.h:36
char host[128]
Server to login to.
Definition: connaccount.h:53
int mutt_idna_to_ascii_lz(const char *input, char **output, uint8_t flags)
static int socket_connect(int fd, struct sockaddr *sa)
set up to connect to a socket fd
Definition: raw.c:69
unsigned short port
Port to connect to.
Definition: connaccount.h:57
int fd
Socket file descriptor.
Definition: connection.h:44
#define mutt_message(...)
Definition: logging.h:87
#define FREE(x)
Definition: memory.h:40
struct ConfigSubset * sub
Inherited config items.
Definition: neomutt.h:39
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_sasl_conn_open()

static int mutt_sasl_conn_open ( struct Connection conn)
static

empty wrapper for underlying open function - Implements Connection::open() -We don't know in advance that a connection will use SASL, so we replace conn's methods with sasl methods when authentication is successful, using mutt_sasl_setup_conn

Definition at line 426 of file sasl.c.

427 {
428  struct SaslSockData *sasldata = conn->sockdata;
429  conn->sockdata = sasldata->sockdata;
430  int rc = sasldata->open(conn);
431  conn->sockdata = sasldata;
432 
433  return rc;
434 }
SASL authentication API -.
Definition: sasl.c:60
void * sockdata
Backend-specific socket data.
Definition: connection.h:46
void * sockdata
Underlying socket data.
Definition: sasl.c:71
int(* open)(struct Connection *conn)
Open a socket Connection - Implements Connection::open() -.
Definition: sasl.c:76
+ Here is the caller graph for this function:

◆ tunnel_socket_open()

static int tunnel_socket_open ( struct Connection conn)
static

Open a tunnel socket - Implements Connection::open() -.

Definition at line 57 of file tunnel.c.

58 {
59  int pin[2], pout[2];
60 
61  struct TunnelSockData *tunnel = mutt_mem_malloc(sizeof(struct TunnelSockData));
62  conn->sockdata = tunnel;
63 
64  const char *const c_tunnel = cs_subset_string(NeoMutt->sub, "tunnel");
65  mutt_message(_("Connecting with \"%s\"..."), c_tunnel);
66 
67  int rc = pipe(pin);
68  if (rc == -1)
69  {
70  mutt_perror("pipe");
71  FREE(&conn->sockdata);
72  return -1;
73  }
74  rc = pipe(pout);
75  if (rc == -1)
76  {
77  mutt_perror("pipe");
78  close(pin[0]);
79  close(pin[1]);
80  FREE(&conn->sockdata);
81  return -1;
82  }
83 
85  int pid = fork();
86  if (pid == 0)
87  {
89  const int fd_null = open("/dev/null", O_RDWR);
90  if ((fd_null < 0) || (dup2(pout[0], STDIN_FILENO) < 0) ||
91  (dup2(pin[1], STDOUT_FILENO) < 0) || (dup2(fd_null, STDERR_FILENO) < 0))
92  {
93  _exit(127);
94  }
95  close(pin[0]);
96  close(pin[1]);
97  close(pout[0]);
98  close(pout[1]);
99  close(fd_null);
100 
101  /* Don't let the subprocess think it can use the controlling tty */
102  setsid();
103 
104  execle(EXEC_SHELL, "sh", "-c", c_tunnel, NULL, mutt_envlist_getlist());
105  _exit(127);
106  }
108 
109  if (pid == -1)
110  {
111  mutt_perror("fork");
112  close(pin[0]);
113  close(pin[1]);
114  close(pout[0]);
115  close(pout[1]);
116  FREE(&conn->sockdata);
117  return -1;
118  }
119  if ((close(pin[1]) < 0) || (close(pout[0]) < 0))
120  mutt_perror("close");
121 
122  fcntl(pin[0], F_SETFD, FD_CLOEXEC);
123  fcntl(pout[1], F_SETFD, FD_CLOEXEC);
124 
125  tunnel->fd_read = pin[0];
126  tunnel->fd_write = pout[1];
127  tunnel->pid = pid;
128 
129  conn->fd = 42; /* stupid hack */
130 
131  return 0;
132 }
pid_t pid
Process ID of tunnel program.
Definition: tunnel.c:49
void mutt_sig_block_system(void)
Block signals before calling exec()
Definition: signal.c:183
int fd_read
File descriptor to read from.
Definition: tunnel.c:50
void * sockdata
Backend-specific socket data.
Definition: connection.h:46
#define _(a)
Definition: message.h:28
#define mutt_perror(...)
Definition: logging.h:89
Container for Accounts, Notifications.
Definition: neomutt.h:36
#define EXEC_SHELL
Definition: filter.h:27
A network tunnel (pair of sockets)
Definition: tunnel.c:47
void mutt_sig_unblock_system(bool restore)
Restore previously blocked signals.
Definition: signal.c:207
int fd
Socket file descriptor.
Definition: connection.h:44
void * mutt_mem_malloc(size_t size)
Allocate memory on the heap.
Definition: memory.c:90
const char * cs_subset_string(const struct ConfigSubset *sub, const char *name)
Get a string config item by name.
Definition: helpers.c:317
int fd_write
File descriptor to write to.
Definition: tunnel.c:51
#define mutt_message(...)
Definition: logging.h:87
#define FREE(x)
Definition: memory.h:40
struct ConfigSubset * sub
Inherited config items.
Definition: neomutt.h:39
char ** mutt_envlist_getlist(void)
Get the private environment.
Definition: envlist.c:169
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ zstrm_open()

static int zstrm_open ( struct Connection conn)
static

Open a socket - Implements Connection::open() -.

Return values
-1Always

Cannot open a zlib connection, must wrap an existing one

Definition at line 89 of file zstrm.c.

90 {
91  return -1;
92 }
+ Here is the caller graph for this function:

Variable Documentation

◆ open

int(* SaslSockData::open) (struct Connection *conn)

Open a socket Connection - Implements Connection::open() -.

Definition at line 76 of file sasl.c.