}
else {
char *value;
-
+ char *endp;
value = strchr(*date_header, ':');
if(!value) {
*date_header = NULL;
++value;
while(ISBLANK(*value))
++value;
- strncpy(timestamp, value, TIMESTAMP_SIZE - 1);
- timestamp[TIMESTAMP_SIZE - 1] = 0;
+ endp = value;
+ while(*endp && ISALNUM(*endp))
+ ++endp;
+ /* 16 bytes => "19700101T000000Z" */
+ if((endp - value) == TIMESTAMP_SIZE - 1) {
+ memcpy(timestamp, value, TIMESTAMP_SIZE - 1);
+ timestamp[TIMESTAMP_SIZE - 1] = 0;
+ }
+ else
+ /* bad timestamp length */
+ timestamp[0] = 0;
*date_header = NULL;
}
result = CURLE_URL_MALFORMAT;
goto fail;
}
- strncpy(service, hostname, len);
+ memcpy(service, hostname, len);
service[len] = '\0';
infof(data, "aws_sigv4: picked service %s from host", service);
result = CURLE_URL_MALFORMAT;
goto fail;
}
- strncpy(region, reg, len);
+ memcpy(region, reg, len);
region[len] = '\0';
infof(data, "aws_sigv4: picked region %s from host", region);
}
* Returns NULL if no error message was found for error code.
*/
static const char *
-get_winsock_error (int err, char *buf, size_t len)
+get_winsock_error(int err, char *buf, size_t len)
{
#ifndef CURL_DISABLE_VERBOSE_STRINGS
const char *p;
#endif
- if(!len)
+ /* 41 bytes is the longest error string */
+ DEBUGASSERT(len > 41);
+ if(!len || len < 41)
return NULL;
*buf = '\0';
default:
return NULL;
}
- strncpy(buf, p, len);
- buf [len-1] = '\0';
+ memcpy(buf, p, len - 1);
+ buf[len - 1] = '\0';
return buf;
#endif
}
#endif
int old_errno = errno;
char *p;
- size_t max;
if(!buflen)
return NULL;
DEBUGASSERT(err >= 0);
#endif
- max = buflen - 1;
*buf = '\0';
#if defined(_WIN32) || defined(_WIN32_WCE)
#if defined(_WIN32)
/* 'sys_nerr' is the maximum errno number, it is not widely portable */
if(err >= 0 && err < sys_nerr)
- strncpy(buf, sys_errlist[err], max);
+ msnprintf(buf, buflen, "%s", sys_errlist[err]);
else
#endif
{
if(
#ifdef USE_WINSOCK
- !get_winsock_error(err, buf, max) &&
+ !get_winsock_error(err, buf, buflen) &&
#endif
- !get_winapi_error((DWORD)err, buf, max))
- msnprintf(buf, max, "Unknown error %d (%#x)", err, err);
+ !get_winapi_error((DWORD)err, buf, buflen))
+ msnprintf(buf, buflen, "Unknown error %d (%#x)", err, err);
}
#else /* not Windows coming up */
* storage is supplied via 'strerrbuf' and 'buflen' to hold the generated
* message string, or EINVAL if 'errnum' is not a valid error number.
*/
- if(0 != strerror_r(err, buf, max)) {
+ if(0 != strerror_r(err, buf, buflen)) {
if('\0' == buf[0])
- msnprintf(buf, max, "Unknown error %d", err);
+ msnprintf(buf, buflen, "Unknown error %d", err);
}
#elif defined(HAVE_STRERROR_R) && defined(HAVE_GLIBC_STRERROR_R)
/*
char buffer[256];
char *msg = strerror_r(err, buffer, sizeof(buffer));
if(msg)
- strncpy(buf, msg, max);
+ msnprintf(buf, buflen, "%s", msg);
else
- msnprintf(buf, max, "Unknown error %d", err);
+ msnprintf(buf, buflen, "Unknown error %d", err);
}
#else
{
/* !checksrc! disable STRERROR 1 */
const char *msg = strerror(err);
if(msg)
- strncpy(buf, msg, max);
+ msnprintf(buf, buflen, "%s", msg);
else
- msnprintf(buf, max, "Unknown error %d", err);
+ msnprintf(buf, buflen, "Unknown error %d", err);
}
#endif
#endif /* end of not Windows */
- buf[max] = '\0'; /* make sure the string is null-terminated */
-
/* strip trailing '\r\n' or '\n'. */
p = strrchr(buf, '\n');
if(p && (p - buf) >= 2)
#else
{
const char *txt = (err == ERROR_SUCCESS) ? "No error" : "Error";
- strncpy(buf, txt, buflen);
- buf[buflen - 1] = '\0';
+ if(strlen(txt) < buflen)
+ strcpy(buf, txt);
}
#endif
err);
}
else {
- char txtbuf[80];
char msgbuf[256];
-
- msnprintf(txtbuf, sizeof(txtbuf), "%s (0x%08X)", txt, err);
-
if(get_winapi_error(err, msgbuf, sizeof(msgbuf)))
- msnprintf(buf, buflen, "%s - %s", txtbuf, msgbuf);
- else {
- strncpy(buf, txtbuf, buflen);
- buf[buflen - 1] = '\0';
- }
+ msnprintf(buf, buflen, "%s (0x%08X) - %s", txt, err, msgbuf);
+ else
+ msnprintf(buf, buflen, "%s (0x%08X)", txt, err);
}
#else
txt = "No error";
else
txt = "Error";
- strncpy(buf, txt, buflen);
- buf[buflen - 1] = '\0';
+ if(buflen > strlen(txt))
+ strcpy(buf, txt);
#endif
if(errno != old_errno)
case 5:
/* Terminal type */
if(strncasecompare(option, "TTYPE", 5)) {
- strncpy(tn->subopt_ttype, arg, 31);
- tn->subopt_ttype[31] = 0; /* String termination */
- tn->us_preferred[CURL_TELOPT_TTYPE] = CURL_YES;
+ size_t l = strlen(arg);
+ if(l < sizeof(tn->subopt_ttype)) {
+ strcpy(tn->subopt_ttype, arg);
+ tn->us_preferred[CURL_TELOPT_TTYPE] = CURL_YES;
+ break;
+ }
}
- else
- result = CURLE_UNKNOWN_OPTION;
+ result = CURLE_UNKNOWN_OPTION;
break;
case 8:
/* Display variable */
if(strncasecompare(option, "XDISPLOC", 8)) {
- strncpy(tn->subopt_xdisploc, arg, 127);
- tn->subopt_xdisploc[127] = 0; /* String termination */
- tn->us_preferred[CURL_TELOPT_XDISPLOC] = CURL_YES;
+ size_t l = strlen(arg);
+ if(l < sizeof(tn->subopt_xdisploc)) {
+ strcpy(tn->subopt_xdisploc, arg);
+ tn->us_preferred[CURL_TELOPT_XDISPLOC] = CURL_YES;
+ break;
+ }
}
- else
- result = CURLE_UNKNOWN_OPTION;
+ result = CURLE_UNKNOWN_OPTION;
break;
case 7:
{
uint16_t selected_ciphers[NUM_OF_CIPHERS];
size_t selected_count = 0;
- char cipher_name[CIPHER_NAME_BUF_LEN];
const char *cipher_start = ciphers;
const char *cipher_end;
size_t i, j;
return CURLE_SSL_CIPHER;
while(true) {
+ const char *cipher;
+ size_t clen;
+
/* Extract the next cipher name from the ciphers string */
while(is_separator(*cipher_start))
++cipher_start;
- if(*cipher_start == '\0')
+ if(!*cipher_start)
break;
cipher_end = cipher_start;
- while(*cipher_end != '\0' && !is_separator(*cipher_end))
+ while(*cipher_end && !is_separator(*cipher_end))
++cipher_end;
- j = cipher_end - cipher_start < CIPHER_NAME_BUF_LEN - 1 ?
- cipher_end - cipher_start : CIPHER_NAME_BUF_LEN - 1;
- strncpy(cipher_name, cipher_start, j);
- cipher_name[j] = '\0';
+
+ clen = cipher_end - cipher_start;
+ cipher = cipher_start;
+
cipher_start = cipher_end;
/* Lookup the cipher name in the table of available ciphers. If the cipher
name starts with "TLS_" we do the lookup by IANA name. Otherwise, we try
to match cipher name by an (OpenSSL) alias. */
- if(strncasecompare(cipher_name, "TLS_", 4)) {
+ if(strncasecompare(cipher, "TLS_", 4)) {
for(i = 0; i < NUM_OF_CIPHERS &&
- !strcasecompare(cipher_name, ciphertable[i].name); ++i);
+ (strlen(ciphertable[i].name) == clen) &&
+ !strncasecompare(cipher, ciphertable[i].name, clen); ++i);
}
else {
for(i = 0; i < NUM_OF_CIPHERS &&
- !strcasecompare(cipher_name, ciphertable[i].alias_name); ++i);
+ (strlen(ciphertable[i].alias_name) == clen) &&
+ !strncasecompare(cipher, ciphertable[i].alias_name, clen); ++i);
}
if(i == NUM_OF_CIPHERS) {
- infof(data, "BearSSL: unknown cipher in list: %s", cipher_name);
+ infof(data, "BearSSL: unknown cipher in list: %.*s",
+ (int)clen, cipher);
continue;
}
/* No duplicates allowed */
for(j = 0; j < selected_count &&
- selected_ciphers[j] != ciphertable[i].num; j++);
+ selected_ciphers[j] != ciphertable[i].num; j++);
if(j < selected_count) {
- infof(data, "BearSSL: duplicate cipher in list: %s", cipher_name);
+ infof(data, "BearSSL: duplicate cipher in list: %.*s",
+ (int)clen, cipher);
continue;
}
#endif
if(!*buf) {
- strncpy(buf, (error ? "Unknown error" : "No error"), size);
- buf[size - 1] = '\0';
+ const char *msg = error ? "Unknown error" : "No error";
+ if(strlen(msg) < size)
+ strcpy(buf, msg);
}
return buf;
ossl_strerror(sslerror, error_buffer, sizeof(error_buffer));
else if(sockerr)
Curl_strerror(sockerr, error_buffer, sizeof(error_buffer));
- else {
- strncpy(error_buffer, SSL_ERROR_to_str(err), sizeof(error_buffer));
- error_buffer[sizeof(error_buffer) - 1] = '\0';
- }
+ else
+ msnprintf(error_buffer, sizeof(error_buffer), "%s",
+ SSL_ERROR_to_str(err));
+
failf(data, OSSL_PACKAGE " SSL_write: %s, errno %d",
error_buffer, sockerr);
*curlcode = CURLE_SEND_ERROR;
ossl_strerror(sslerror, error_buffer, sizeof(error_buffer));
else if(sockerr && err == SSL_ERROR_SYSCALL)
Curl_strerror(sockerr, error_buffer, sizeof(error_buffer));
- else {
- strncpy(error_buffer, SSL_ERROR_to_str(err), sizeof(error_buffer));
- error_buffer[sizeof(error_buffer) - 1] = '\0';
- }
+ else
+ msnprintf(error_buffer, sizeof(error_buffer), "%s",
+ SSL_ERROR_to_str(err));
failf(data, OSSL_PACKAGE " SSL_read: %s, errno %d",
error_buffer, sockerr);
*curlcode = CURLE_RECV_ERROR;
return CURLE_OK;
}
#endif
+
+static bool algo(const char *check, char *namep, size_t nlen)
+{
+ return (strlen(check) == nlen) && !strncmp(check, namep, nlen);
+}
+
static CURLcode
schannel_acquire_credential_handle(struct Curl_cfilter *cf,
struct Curl_easy *data)
char *startCur = ciphers13;
int algCount = 0;
- char tmp[LONGEST_ALG_ID] = { 0 };
char *nameEnd;
- size_t n;
disable_aes_gcm_sha384 = TRUE;
disable_aes_gcm_sha256 = TRUE;
disable_aes_ccm_sha256 = TRUE;
while(startCur && (0 != *startCur) && (algCount < remaining_ciphers)) {
+ size_t n;
+ char *namep;
nameEnd = strchr(startCur, ':');
n = nameEnd ? (size_t)(nameEnd - startCur) : strlen(startCur);
+ namep = startCur;
- /* reject too-long cipher names */
- if(n > (LONGEST_ALG_ID - 1)) {
- failf(data, "schannel: Cipher name too long, not checked");
- return CURLE_SSL_CIPHER;
- }
-
- strncpy(tmp, startCur, n);
- tmp[n] = 0;
-
- if(disable_aes_gcm_sha384
- && !strcmp("TLS_AES_256_GCM_SHA384", tmp)) {
+ if(disable_aes_gcm_sha384 &&
+ algo("TLS_AES_256_GCM_SHA384", namep, n)) {
disable_aes_gcm_sha384 = FALSE;
}
else if(disable_aes_gcm_sha256
- && !strcmp("TLS_AES_128_GCM_SHA256", tmp)) {
+ && algo("TLS_AES_128_GCM_SHA256", namep, n)) {
disable_aes_gcm_sha256 = FALSE;
}
else if(disable_chacha_poly
- && !strcmp("TLS_CHACHA20_POLY1305_SHA256", tmp)) {
+ && algo("TLS_CHACHA20_POLY1305_SHA256", namep, n)) {
disable_chacha_poly = FALSE;
}
else if(disable_aes_ccm_8_sha256
- && !strcmp("TLS_AES_128_CCM_8_SHA256", tmp)) {
+ && algo("TLS_AES_128_CCM_8_SHA256", namep, n)) {
disable_aes_ccm_8_sha256 = FALSE;
}
else if(disable_aes_ccm_sha256
- && !strcmp("TLS_AES_128_CCM_SHA256", tmp)) {
+ && algo("TLS_AES_128_CCM_SHA256", namep, n)) {
disable_aes_ccm_sha256 = FALSE;
}
else {
- failf(data, "schannel: Unknown TLS 1.3 cipher: %s", tmp);
+ failf(data, "schannel: Unknown TLS 1.3 cipher: %.*s", (int)n, namep);
return CURLE_SSL_CIPHER;
}
backends_len = p - backends;
}
- if(!size)
- return 0;
-
- if(size <= backends_len) {
- strncpy(buffer, backends, size - 1);
- buffer[size - 1] = '\0';
- return size - 1;
- }
-
- strcpy(buffer, backends);
- return backends_len;
+ if(size && (size < backends_len))
+ strcpy(buffer, backends);
+ else
+ *buffer = 0; /* did not fit */
+ return 0;
}
static int multissl_setup(const struct Curl_ssl *backend)