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

1028{
1029 if (raw_socket_open(conn) < 0)
1030 return -1;
1031
1032 if (tls_negotiate(conn) < 0)
1033 {
1034 tls_socket_close(conn);
1035 return -1;
1036 }
1037
1038 return 0;
1039}
static int tls_negotiate(struct Connection *conn)
Negotiate TLS connection.
Definition: gnutls.c:871
static int tls_socket_close(struct Connection *conn)
Close a TLS socket - Implements Connection::close() -.
Definition: gnutls.c:1002
int raw_socket_open(struct Connection *conn)
Open a socket - Implements Connection::open() -.
Definition: raw.c:130
+ 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: logging2.h:92
#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:379
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 130 of file raw.c.

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

60{
61 int pin[2], pout[2];
62
63 struct TunnelSockData *tunnel = mutt_mem_malloc(sizeof(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 {
91 const int fd_null = open("/dev/null", O_RDWR);
92 if ((fd_null < 0) || (dup2(pout[0], STDIN_FILENO) < 0) ||
93 (dup2(pin[1], STDOUT_FILENO) < 0) || (dup2(fd_null, STDERR_FILENO) < 0))
94 {
95 _exit(127);
96 }
97 close(pin[0]);
98 close(pin[1]);
99 close(pout[0]);
100 close(pout[1]);
101 close(fd_null);
102
103 /* Don't let the subprocess think it can use the controlling tty */
104 setsid();
105
106 execle(EXEC_SHELL, "sh", "-c", c_tunnel, NULL, EnvList);
107 _exit(127);
108 }
110
111 if (pid == -1)
112 {
113 mutt_perror("fork");
114 close(pin[0]);
115 close(pin[1]);
116 close(pout[0]);
117 close(pout[1]);
118 FREE(&conn->sockdata);
119 return -1;
120 }
121 if ((close(pin[1]) < 0) || (close(pout[0]) < 0))
122 mutt_perror("close");
123
124 fcntl(pin[0], F_SETFD, FD_CLOEXEC);
125 fcntl(pout[1], F_SETFD, FD_CLOEXEC);
126
127 tunnel->fd_read = pin[0];
128 tunnel->fd_write = pout[1];
129 tunnel->pid = pid;
130
131 conn->fd = 42; /* stupid hack */
132
133 /* Note we are using ssf as a boolean in this case. See the notes in
134 * conn/connection.h */
135 const bool c_tunnel_is_secure = cs_subset_bool(NeoMutt->sub, "tunnel_is_secure");
136 if (c_tunnel_is_secure)
137 conn->ssf = 1;
138
139 return 0;
140}
const char * cs_subset_string(const struct ConfigSubset *sub, const char *name)
Get a string config item by name.
Definition: helpers.c:292
#define EXEC_SHELL
Definition: filter.h:27
char ** EnvList
Private copy of the environment variables.
Definition: globals.c:85
#define mutt_perror(...)
Definition: logging2.h:93
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:196
void mutt_sig_unblock_system(bool restore)
Restore previously blocked signals.
Definition: signal.c:220
unsigned int ssf
Security strength factor, in bits (see notes)
Definition: connection.h:51
A network tunnel (pair of sockets)
Definition: tunnel.c:50
int fd_read
File descriptor to read from.
Definition: tunnel.c:52
pid_t pid
Process ID of tunnel program.
Definition: tunnel.c:51
int fd_write
File descriptor to write to.
Definition: tunnel.c:53
+ 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 79 of file sasl.c.