NeoMutt  2023-03-22-27-g3cb248
Teaching an old dog new tricks
DOXYGEN

Open a socket Connection. 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() -. 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

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 1026 of file gnutls.c.

1027{
1028 if (raw_socket_open(conn) < 0)
1029 return -1;
1030
1031 if (tls_negotiate(conn) < 0)
1032 {
1033 tls_socket_close(conn);
1034 return -1;
1035 }
1036
1037 return 0;
1038}
static int tls_negotiate(struct Connection *conn)
Negotiate TLS connection.
Definition: gnutls.c:870
static int tls_socket_close(struct Connection *conn)
Close a TLS socket - Implements Connection::close() -.
Definition: gnutls.c:1001
int raw_socket_open(struct Connection *conn)
Open a socket - Implements Connection::open() -.
Definition: raw.c:129
+ 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 352 of file openssl.c.

353{
354 mutt_error(_("SSL disabled due to the lack of entropy"));
355 return -1;
356}
#define mutt_error(...)
Definition: logging.h:87
#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 1311 of file openssl.c.

1312{
1313 if (raw_socket_open(conn) < 0)
1314 return -1;
1315
1316 int rc = ssl_setup(conn);
1317 if (rc)
1318 raw_socket_close(conn);
1319
1320 return rc;
1321}
int raw_socket_close(struct Connection *conn)
Close a socket - Implements Connection::close() -.
Definition: raw.c:378
static int ssl_setup(struct Connection *conn)
Set up SSL on the Connection.
Definition: openssl.c:1194
+ 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 129 of file raw.c.

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

423{
424 struct SaslSockData *sasldata = conn->sockdata;
425 conn->sockdata = sasldata->sockdata;
426 int rc = sasldata->open(conn);
427 conn->sockdata = sasldata;
428
429 return rc;
430}
int(* open)(struct Connection *conn)
Open a socket Connection - Implements Connection::open() -.
Definition: sasl.c:77
void * sockdata
Backend-specific socket data.
Definition: connection.h:56
SASL authentication API -.
Definition: sasl.c:62
void * sockdata
Underlying socket data.
Definition: sasl.c:72
+ 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}
const char * cs_subset_string(const struct ConfigSubset *sub, const char *name)
Get a string config item by name.
Definition: helpers.c:317
char ** mutt_envlist_getlist(void)
Get the private environment.
Definition: envlist.c:169
#define EXEC_SHELL
Definition: filter.h:27
#define mutt_perror(...)
Definition: logging.h:88
void * mutt_mem_malloc(size_t size)
Allocate memory on the heap.
Definition: memory.c:90
void mutt_sig_block_system(void)
Block signals before calling exec()
Definition: signal.c:183
void mutt_sig_unblock_system(bool restore)
Restore previously blocked signals.
Definition: signal.c:207
A network tunnel (pair of sockets)
Definition: tunnel.c:48
int fd_read
File descriptor to read from.
Definition: tunnel.c:50
pid_t pid
Process ID of tunnel program.
Definition: tunnel.c:49
int fd_write
File descriptor to write to.
Definition: tunnel.c:51
+ 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 77 of file sasl.c.