summaryrefslogtreecommitdiffstats
path: root/lib/security.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib/security.c')
-rw-r--r--lib/security.c187
1 files changed, 83 insertions, 104 deletions
diff --git a/lib/security.c b/lib/security.c
index 508c7b4..014bbf1 100644
--- a/lib/security.c
+++ b/lib/security.c
@@ -7,10 +7,10 @@
* rewrite to work around the paragraph 2 in the BSD licenses as explained
* below.
*
- * Copyright (c) 1998, 1999, 2013 Kungliga Tekniska Högskolan
+ * Copyright (c) 1998, 1999 Kungliga Tekniska Högskolan
* (Royal Institute of Technology, Stockholm, Sweden).
*
- * Copyright (C) 2001 - 2013, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 2001 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* All rights reserved.
*
@@ -109,19 +109,12 @@ static char level_to_char(int level) {
return 'P';
}
-static const struct Curl_sec_client_mech * const mechs[] = {
-#ifdef HAVE_GSSAPI
- &Curl_krb5_client_mech,
-#endif
- NULL
-};
-
/* Send an FTP command defined by |message| and the optional arguments. The
function returns the ftp_code. If an error occurs, -1 is returned. */
static int ftp_send_command(struct connectdata *conn, const char *message, ...)
{
int ftp_code;
- ssize_t nread;
+ ssize_t nread=0;
va_list args;
char print_buffer[50];
@@ -129,11 +122,11 @@ static int ftp_send_command(struct connectdata *conn, const char *message, ...)
vsnprintf(print_buffer, sizeof(print_buffer), message, args);
va_end(args);
- if(Curl_ftpsendf(conn, print_buffer) != CURLE_OK) {
+ if(Curl_ftpsendf(conn, print_buffer)) {
ftp_code = -1;
}
else {
- if(Curl_GetFTPResponse(&nread, conn, &ftp_code) != CURLE_OK)
+ if(Curl_GetFTPResponse(&nread, conn, &ftp_code))
ftp_code = -1;
}
@@ -147,20 +140,20 @@ static CURLcode
socket_read(curl_socket_t fd, void *to, size_t len)
{
char *to_p = to;
- CURLcode code;
+ CURLcode result;
ssize_t nread;
while(len > 0) {
- code = Curl_read_plain(fd, to_p, len, &nread);
- if(code == CURLE_OK) {
+ result = Curl_read_plain(fd, to_p, len, &nread);
+ if(!result) {
len -= nread;
to_p += nread;
}
else {
/* FIXME: We are doing a busy wait */
- if(code == CURLE_AGAIN)
+ if(result == CURLE_AGAIN)
continue;
- return code;
+ return result;
}
}
return CURLE_OK;
@@ -175,20 +168,20 @@ socket_write(struct connectdata *conn, curl_socket_t fd, const void *to,
size_t len)
{
const char *to_p = to;
- CURLcode code;
+ CURLcode result;
ssize_t written;
while(len > 0) {
- code = Curl_write_plain(conn, fd, to_p, len, &written);
- if(code == CURLE_OK) {
+ result = Curl_write_plain(conn, fd, to_p, len, &written);
+ if(!result) {
len -= written;
to_p += written;
}
else {
/* FIXME: We are doing a busy wait */
- if(code == CURLE_AGAIN)
+ if(result == CURLE_AGAIN)
continue;
- return code;
+ return result;
}
}
return CURLE_OK;
@@ -200,11 +193,11 @@ static CURLcode read_data(struct connectdata *conn,
{
int len;
void* tmp;
- CURLcode ret;
+ CURLcode result;
- ret = socket_read(fd, &len, sizeof(len));
- if(ret != CURLE_OK)
- return ret;
+ result = socket_read(fd, &len, sizeof(len));
+ if(result)
+ return result;
len = ntohl(len);
tmp = realloc(buf->data, len);
@@ -212,9 +205,9 @@ static CURLcode read_data(struct connectdata *conn,
return CURLE_OUT_OF_MEMORY;
buf->data = tmp;
- ret = socket_read(fd, buf->data, len);
- if(ret != CURLE_OK)
- return ret;
+ result = socket_read(fd, buf->data, len);
+ if(result)
+ return result;
buf->size = conn->mech->decode(conn->app_data, buf->data, len,
conn->data_prot, conn);
buf->index = 0;
@@ -256,7 +249,7 @@ static ssize_t sec_recv(struct connectdata *conn, int sockindex,
buffer += bytes_read;
while(len > 0) {
- if(read_data(conn, fd, &conn->in_buffer) != CURLE_OK)
+ if(read_data(conn, fd, &conn->in_buffer))
return -1;
if(conn->in_buffer.size == 0) {
if(bytes_read > 0)
@@ -295,7 +288,7 @@ static void do_sec_send(struct connectdata *conn, curl_socket_t fd,
prot_level = conn->command_prot;
}
bytes = conn->mech->encode(conn->app_data, from, length, prot_level,
- (void**)&buffer, conn);
+ (void**)&buffer);
if(!buffer || bytes <= 0)
return; /* error */
@@ -332,7 +325,6 @@ static void do_sec_send(struct connectdata *conn, curl_socket_t fd,
static ssize_t sec_write(struct connectdata *conn, curl_socket_t fd,
const char *buffer, size_t length)
{
- /* FIXME: Check for overflow */
ssize_t tx = 0, len = conn->buffer_size;
len -= conn->mech->overhead(conn->app_data, conn->data_prot,
@@ -340,10 +332,9 @@ static ssize_t sec_write(struct connectdata *conn, curl_socket_t fd,
if(len <= 0)
len = length;
while(length) {
- if(len >= 0 || length < (size_t)len) {
- /* FIXME: Check for overflow. */
+ if(length < (size_t)len)
len = length;
- }
+
do_sec_send(conn, fd, buffer, curlx_sztosi(len));
length -= len;
buffer += len;
@@ -368,7 +359,7 @@ int Curl_sec_read_msg(struct connectdata *conn, char *buffer,
int */
int decoded_len;
char *buf;
- int ret_code;
+ int ret_code = 0;
size_t decoded_sz = 0;
CURLcode error;
@@ -397,13 +388,13 @@ int Curl_sec_read_msg(struct connectdata *conn, char *buffer,
}
buf[decoded_len] = '\0';
- DEBUGASSERT(decoded_len > 3);
- if(buf[3] == '-')
- ret_code = 0;
- else {
- /* Check for error? */
- sscanf(buf, "%d", &ret_code);
- }
+ if(decoded_len <= 3)
+ /* suspiciously short */
+ return 0;
+
+ if(buf[3] != '-')
+ /* safe to ignore return code */
+ (void)sscanf(buf, "%d", &ret_code);
if(buf[decoded_len - 1] == '\n')
buf[decoded_len - 1] = '\0';
@@ -446,8 +437,8 @@ static int sec_set_protection_level(struct connectdata *conn)
pbsz = strstr(conn->data->state.buffer, "PBSZ=");
if(pbsz) {
- /* FIXME: Checks for errors in sscanf? */
- sscanf(pbsz, "PBSZ=%u", &buffer_size);
+ /* ignore return code, use default value if it fails */
+ (void)sscanf(pbsz, "PBSZ=%u", &buffer_size);
if(buffer_size < conn->buffer_size)
conn->buffer_size = buffer_size;
}
@@ -486,72 +477,63 @@ static CURLcode choose_mech(struct connectdata *conn)
{
int ret;
struct SessionHandle *data = conn->data;
- const struct Curl_sec_client_mech * const *mech;
void *tmp_allocation;
- const char *mech_name;
-
- for(mech = mechs; (*mech); ++mech) {
- mech_name = (*mech)->name;
- /* We have no mechanism with a NULL name but keep this check */
- DEBUGASSERT(mech_name != NULL);
- if(mech_name == NULL) {
- infof(data, "Skipping mechanism with empty name (%p)\n", (void *)mech);
- continue;
- }
- tmp_allocation = realloc(conn->app_data, (*mech)->size);
- if(tmp_allocation == NULL) {
- failf(data, "Failed realloc of size %u", (*mech)->size);
- mech = NULL;
- return CURLE_OUT_OF_MEMORY;
- }
- conn->app_data = tmp_allocation;
+ const struct Curl_sec_client_mech *mech = &Curl_krb5_client_mech;
- if((*mech)->init) {
- ret = (*mech)->init(conn->app_data);
- if(ret != 0) {
- infof(data, "Failed initialization for %s. Skipping it.\n", mech_name);
- continue;
- }
+ tmp_allocation = realloc(conn->app_data, mech->size);
+ if(tmp_allocation == NULL) {
+ failf(data, "Failed realloc of size %u", mech->size);
+ mech = NULL;
+ return CURLE_OUT_OF_MEMORY;
+ }
+ conn->app_data = tmp_allocation;
+
+ if(mech->init) {
+ ret = mech->init(conn->app_data);
+ if(ret) {
+ infof(data, "Failed initialization for %s. Skipping it.\n",
+ mech->name);
+ return CURLE_FAILED_INIT;
}
+ }
- infof(data, "Trying mechanism %s...\n", mech_name);
- ret = ftp_send_command(conn, "AUTH %s", mech_name);
- if(ret < 0)
- /* FIXME: This error is too generic but it is OK for now. */
- return CURLE_COULDNT_CONNECT;
-
- if(ret/100 != 3) {
- switch(ret) {
- case 504:
- infof(data, "Mechanism %s is not supported by the server (server "
- "returned ftp code: 504).\n", mech_name);
- break;
- case 534:
- infof(data, "Mechanism %s was rejected by the server (server returned "
- "ftp code: 534).\n", mech_name);
- break;
- default:
- if(ret/100 == 5) {
- infof(data, "server does not support the security extensions\n");
- return CURLE_USE_SSL_FAILED;
- }
- break;
+ infof(data, "Trying mechanism %s...\n", mech->name);
+ ret = ftp_send_command(conn, "AUTH %s", mech->name);
+ if(ret < 0)
+ /* FIXME: This error is too generic but it is OK for now. */
+ return CURLE_COULDNT_CONNECT;
+
+ if(ret/100 != 3) {
+ switch(ret) {
+ case 504:
+ infof(data, "Mechanism %s is not supported by the server (server "
+ "returned ftp code: 504).\n", mech->name);
+ break;
+ case 534:
+ infof(data, "Mechanism %s was rejected by the server (server returned "
+ "ftp code: 534).\n", mech->name);
+ break;
+ default:
+ if(ret/100 == 5) {
+ infof(data, "server does not support the security extensions\n");
+ return CURLE_USE_SSL_FAILED;
}
- continue;
+ break;
}
+ return CURLE_LOGIN_DENIED;
+ }
- /* Authenticate */
- ret = (*mech)->auth(conn->app_data, conn);
+ /* Authenticate */
+ ret = mech->auth(conn->app_data, conn);
- if(ret == AUTH_CONTINUE)
- continue;
- else if(ret != AUTH_OK) {
+ if(ret != AUTH_CONTINUE) {
+ if(ret != AUTH_OK) {
/* Mechanism has dumped the error to stderr, don't error here. */
return -1;
}
DEBUGASSERT(ret == AUTH_OK);
- conn->mech = *mech;
+ conn->mech = mech;
conn->sec_complete = 1;
conn->recv[FIRSTSOCKET] = sec_recv;
conn->send[FIRSTSOCKET] = sec_send;
@@ -561,10 +543,9 @@ static CURLcode choose_mech(struct connectdata *conn)
/* Set the requested protection level */
/* BLOCKING */
(void)sec_set_protection_level(conn);
- break;
}
- return mech != NULL ? CURLE_OK : CURLE_FAILED_INIT;
+ return CURLE_OK;
}
CURLcode
@@ -579,10 +560,8 @@ Curl_sec_end(struct connectdata *conn)
{
if(conn->mech != NULL && conn->mech->end)
conn->mech->end(conn->app_data);
- if(conn->app_data) {
- free(conn->app_data);
- conn->app_data = NULL;
- }
+ free(conn->app_data);
+ conn->app_data = NULL;
if(conn->in_buffer.data) {
free(conn->in_buffer.data);
conn->in_buffer.data = NULL;