summaryrefslogtreecommitdiff
path: root/src/lib/libcrypto/bio/b_sock.c
diff options
context:
space:
mode:
authorjsing <>2014-06-22 14:41:10 +0000
committerjsing <>2014-06-22 14:41:10 +0000
commit0e48583e384b473bddadeed479e2ac76911814bc (patch)
treea48d59c793ed018ac1b68d77e5b9dc0708d3bc84 /src/lib/libcrypto/bio/b_sock.c
parentfc342088a9e9234b5e22294af9d7a3b490705097 (diff)
downloadopenbsd-0e48583e384b473bddadeed479e2ac76911814bc.tar.gz
openbsd-0e48583e384b473bddadeed479e2ac76911814bc.tar.bz2
openbsd-0e48583e384b473bddadeed479e2ac76911814bc.zip
In BIO_get_port(), use strol() with appropriate range checks rather than
an atoi() followed by an unsigned short cast. This stops things like "-1" and "66536" from being considered to be "valid" port numbers. ok beck@ deraadt@
Diffstat (limited to 'src/lib/libcrypto/bio/b_sock.c')
-rw-r--r--src/lib/libcrypto/bio/b_sock.c78
1 files changed, 46 insertions, 32 deletions
diff --git a/src/lib/libcrypto/bio/b_sock.c b/src/lib/libcrypto/bio/b_sock.c
index 69be7861f0..ddd2abb625 100644
--- a/src/lib/libcrypto/bio/b_sock.c
+++ b/src/lib/libcrypto/bio/b_sock.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: b_sock.c,v 1.38 2014/06/12 15:49:28 deraadt Exp $ */ 1/* $OpenBSD: b_sock.c,v 1.39 2014/06/22 14:41:10 jsing Exp $ */
2/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) 2/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
3 * All rights reserved. 3 * All rights reserved.
4 * 4 *
@@ -138,42 +138,56 @@ err:
138int 138int
139BIO_get_port(const char *str, unsigned short *port_ptr) 139BIO_get_port(const char *str, unsigned short *port_ptr)
140{ 140{
141 int i;
142 struct servent *s; 141 struct servent *s;
142 long port;
143 char *ep;
143 144
144 if (str == NULL) { 145 if (str == NULL) {
145 BIOerr(BIO_F_BIO_GET_PORT, BIO_R_NO_PORT_DEFINED); 146 BIOerr(BIO_F_BIO_GET_PORT, BIO_R_NO_PORT_SPECIFIED);
146 return (0); 147 return (0);
147 } 148 }
148 i = atoi(str); 149
149 if (i != 0) 150 errno = 0;
150 *port_ptr = (unsigned short)i; 151 port = strtol(str, &ep, 10);
151 else { 152 if (str[0] != '\0' && *ep == '\0') {
152 CRYPTO_w_lock(CRYPTO_LOCK_GETSERVBYNAME); 153 if (errno == ERANGE && (port == LONG_MAX || port == LONG_MIN)) {
153 s = getservbyname(str, "tcp"); 154 BIOerr(BIO_F_BIO_GET_PORT, BIO_R_INVALID_PORT_NUMBER);
154 if (s != NULL) 155 return (0);
155 *port_ptr = ntohs((unsigned short)s->s_port); 156 }
156 CRYPTO_w_unlock(CRYPTO_LOCK_GETSERVBYNAME); 157 if (port < 0 || port > 65535) {
157 if (s == NULL) { 158 BIOerr(BIO_F_BIO_GET_PORT, BIO_R_INVALID_PORT_NUMBER);
158 if (strcmp(str, "http") == 0) 159 return (0);
159 *port_ptr = 80; 160 }
160 else if (strcmp(str, "telnet") == 0) 161
161 *port_ptr = 23; 162 *port_ptr = (unsigned short)port;
162 else if (strcmp(str, "socks") == 0) 163 return (1);
163 *port_ptr = 1080; 164 }
164 else if (strcmp(str, "https") == 0) 165
165 *port_ptr = 443; 166 CRYPTO_w_lock(CRYPTO_LOCK_GETSERVBYNAME);
166 else if (strcmp(str, "ssl") == 0) 167 s = getservbyname(str, "tcp");
167 *port_ptr = 443; 168 if (s != NULL)
168 else if (strcmp(str, "ftp") == 0) 169 *port_ptr = ntohs((unsigned short)s->s_port);
169 *port_ptr = 21; 170 CRYPTO_w_unlock(CRYPTO_LOCK_GETSERVBYNAME);
170 else if (strcmp(str, "gopher") == 0) 171
171 *port_ptr = 70; 172 if (s == NULL) {
172 else { 173 if (strcmp(str, "http") == 0)
173 SYSerr(SYS_F_GETSERVBYNAME, errno); 174 *port_ptr = 80;
174 ERR_asprintf_error_data("service='%s'", str); 175 else if (strcmp(str, "telnet") == 0)
175 return (0); 176 *port_ptr = 23;
176 } 177 else if (strcmp(str, "socks") == 0)
178 *port_ptr = 1080;
179 else if (strcmp(str, "https") == 0)
180 *port_ptr = 443;
181 else if (strcmp(str, "ssl") == 0)
182 *port_ptr = 443;
183 else if (strcmp(str, "ftp") == 0)
184 *port_ptr = 21;
185 else if (strcmp(str, "gopher") == 0)
186 *port_ptr = 70;
187 else {
188 SYSerr(SYS_F_GETSERVBYNAME, errno);
189 ERR_asprintf_error_data("service='%s'", str);
190 return (0);
177 } 191 }
178 } 192 }
179 return (1); 193 return (1);