NeoMutt  2025-12-11-980-ge38c27
Teaching an old dog new tricks
DOXYGEN
Loading...
Searching...
No Matches

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() -.
 
static int ssl_socket_open_err (struct Connection *conn)
 Error callback for opening an SSL connection - Implements Connection::open() -.
 
static int ssl_socket_open (struct Connection *conn)
 Open an SSL socket - Implements Connection::open() -.
 
int raw_socket_open (struct Connection *conn)
 Open a socket - Implements Connection::open() -.
 
static int mutt_sasl_conn_open (struct Connection *conn)
 Empty wrapper for underlying open function - Implements Connection::open() -.
 
static int tunnel_socket_open (struct Connection *conn)
 Open a tunnel socket - Implements Connection::open() -.
 
static int zstrm_open (struct Connection *conn)
 Open a socket - Implements Connection::open() -.
 

Variables

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

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

1047{
1048 if (raw_socket_open(conn) < 0)
1049 return -1;
1050
1051 if (tls_negotiate(conn) < 0)
1052 {
1053 tls_socket_close(conn);
1054 return -1;
1055 }
1056
1057 return 0;
1058}
static int tls_negotiate(struct Connection *conn)
Negotiate TLS connection.
Definition gnutls.c:884
static int tls_socket_close(struct Connection *conn)
Close a TLS socket - Implements Connection::close() -.
Definition gnutls.c:1021
int raw_socket_open(struct Connection *conn)
Open a socket - Implements Connection::open() -.
Definition raw.c:147
+ 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 358 of file openssl.c.

359{
360 mutt_error(_("SSL disabled due to the lack of entropy"));
361 return -1;
362}
#define mutt_error(...)
Definition logging2.h:94
#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 1329 of file openssl.c.

1330{
1331 if (raw_socket_open(conn) < 0)
1332 return -1;
1333
1334 int rc = ssl_setup(conn);
1335 if (rc)
1336 raw_socket_close(conn);
1337
1338 return rc;
1339}
int raw_socket_close(struct Connection *conn)
Close a socket - Implements Connection::close() -.
Definition raw.c:392
static int ssl_setup(struct Connection *conn)
Set up SSL on the Connection.
Definition openssl.c:1222
+ 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 147 of file raw.c.

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

433{
434 struct SaslSockData *sasldata = conn->sockdata;
435 conn->sockdata = sasldata->sockdata;
436 int rc = sasldata->open(conn);
437 conn->sockdata = sasldata;
438
439 return rc;
440}
int(* open)(struct Connection *conn)
Open a socket Connection - Implements Connection::open() -.
Definition sasl.c:81
void * sockdata
Backend-specific socket data.
Definition connection.h:55
SASL authentication API -.
Definition sasl.c:66
void * sockdata
Underlying socket data.
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 58 of file tunnel.c.

59{
60 int pin[2] = { 0 };
61 int pout[2] = { 0 };
62
63 struct TunnelSockData *tunnel = MUTT_MEM_MALLOC(1, struct TunnelSockData);
64 conn->sockdata = tunnel;
65
66 const char *const c_tunnel = cs_subset_string(NeoMutt->sub, "tunnel");
67 mutt_message(_("Connecting with \"%s\"..."), c_tunnel);
68
69 int rc = pipe(pin);
70 if (rc == -1)
71 {
72 mutt_perror("pipe");
73 FREE(&conn->sockdata);
74 return -1;
75 }
76 rc = pipe(pout);
77 if (rc == -1)
78 {
79 mutt_perror("pipe");
80 close(pin[0]);
81 close(pin[1]);
82 FREE(&conn->sockdata);
83 return -1;
84 }
85
87 int pid = fork();
88 if (pid == 0)
89 {
92 const int fd_null = open("/dev/null", O_RDWR);
93 if ((fd_null < 0) || (dup2(pout[0], STDIN_FILENO) < 0) ||
94 (dup2(pin[1], STDOUT_FILENO) < 0) || (dup2(fd_null, STDERR_FILENO) < 0))
95 {
96 _exit(127);
97 }
98 close(pin[0]);
99 close(pin[1]);
100 close(pout[0]);
101 close(pout[1]);
102 close(fd_null);
103
104 /* Don't let the subprocess think it can use the controlling tty */
105 setsid();
106
107 execle(EXEC_SHELL, "sh", "-c", c_tunnel, NULL, NeoMutt->env);
108 _exit(127);
109 }
111
112 if (pid == -1)
113 {
114 mutt_perror("fork");
115 close(pin[0]);
116 close(pin[1]);
117 close(pout[0]);
118 close(pout[1]);
119 FREE(&conn->sockdata);
120 return -1;
121 }
122 if ((close(pin[1]) < 0) || (close(pout[0]) < 0))
123 mutt_perror("close");
124
125 // These are unlikely to fail
126 (void) fcntl(pin[0], F_SETFD, FD_CLOEXEC);
127 (void) fcntl(pout[1], F_SETFD, FD_CLOEXEC);
128
129 tunnel->fd_read = pin[0];
130 tunnel->fd_write = pout[1];
131 tunnel->pid = pid;
132
133 conn->fd = 42; /* stupid hack */
134
135 /* Note we are using ssf as a boolean in this case. See the notes in
136 * conn/connection.h */
137 const bool c_tunnel_is_secure = cs_subset_bool(NeoMutt->sub, "tunnel_is_secure");
138 if (c_tunnel_is_secure)
139 conn->ssf = 1;
140
141 return 0;
142}
const char * cs_subset_string(const struct ConfigSubset *sub, const char *name)
Get a string config item by name.
Definition helpers.c:291
#define mutt_perror(...)
Definition logging2.h:95
#define MUTT_MEM_MALLOC(n, type)
Definition memory.h:53
#define EXEC_SHELL
Default shell to use for executing commands.
Definition filter.h:30
void mutt_sig_reset_child_signals(void)
Reset ignored signals back to the default.
Definition signal.c:336
void mutt_sig_block_system(void)
Block signals before calling exec()
Definition signal.c:260
void mutt_sig_unblock_system(bool restore)
Restore previously blocked signals.
Definition signal.c:284
unsigned int ssf
Security strength factor, in bits (see notes)
Definition connection.h:50
char ** env
Private copy of the environment variables.
Definition neomutt.h:57
A network tunnel (pair of sockets)
Definition tunnel.c:49
int fd_read
File descriptor to read from.
Definition tunnel.c:51
pid_t pid
Process ID of tunnel program.
Definition tunnel.c:50
int fd_write
File descriptor to write to.
Definition tunnel.c:52
+ 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 92 of file zstrm.c.

93{
94 return -1;
95}
+ 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 81 of file sasl.c.