NeoMutt  2022-04-29-249-gaae397
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:117
+ 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:362
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 117 of file raw.c.

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