* \___|\___/|_| \_\_____|
*
* Copyright (C) 2014, Bill Nagel <wnagel@tycoint.com>, Exacq Technologies
- * Copyright (C) 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 2016-2017, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
#include "curl_setup.h"
-#if !defined(CURL_DISABLE_SMB) && defined(USE_NTLM) && \
- (CURL_SIZEOF_CURL_OFF_T > 4)
+#if !defined(CURL_DISABLE_SMB) && defined(USE_NTLM) && \
+ (CURL_SIZEOF_CURL_OFF_T > 4)
#if !defined(USE_WINDOWS_SSPI) || defined(USE_WIN32_CRYPTO)
#ifdef HAVE_PROCESS_H
#include <process.h>
+#ifdef CURL_WINDOWS_APP
+#define getpid GetCurrentProcessId
+#else
#define getpid _getpid
#endif
+#endif
#include "smb.h"
#include "urldata.h"
#define SERVICENAME "?????"
/* Append a string to an SMB message */
-#define MSGCAT(str) \
- strcpy(p, (str)); \
+#define MSGCAT(str) \
+ strcpy(p, (str)); \
p += strlen(str);
/* Append a null-terminated string to an SMB message */
-#define MSGCATNULL(str) \
- strcpy(p, (str)); \
+#define MSGCATNULL(str) \
+ strcpy(p, (str)); \
p += strlen(str) + 1;
/* SMB is mostly little endian */
#if (defined(__BYTE_ORDER__) && __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__) || \
- defined(__OS400__)
+ defined(__OS400__)
static unsigned short smb_swap16(unsigned short x)
{
return (unsigned short) ((x << 8) | ((x >> 8) & 0xff));
static unsigned int smb_swap32(unsigned int x)
{
return (x << 24) | ((x << 8) & 0xff0000) | ((x >> 8) & 0xff00) |
- ((x >> 24) & 0xff);
+ ((x >> 24) & 0xff);
}
#ifdef HAVE_LONGLONG
static unsigned long long smb_swap64(unsigned long long x)
{
return ((unsigned long long) smb_swap32((unsigned int) x) << 32) |
- smb_swap32((unsigned int) (x >> 32));
+ smb_swap32((unsigned int) (x >> 32));
}
#else
static unsigned __int64 smb_swap64(unsigned __int64 x)
{
return ((unsigned __int64) smb_swap32((unsigned int) x) << 32) |
- smb_swap32((unsigned int) (x >> 32));
+ smb_swap32((unsigned int) (x >> 32));
}
#endif
#else
if(smb->state != newstate)
infof(conn->data, "SMB conn %p state change from %s to %s\n",
- (void *)smb, names[smb->state], names[newstate]);
+ (void *)smb, names[smb->state], names[newstate]);
#endif
smb->state = newstate;
if(req->state != newstate)
infof(conn->data, "SMB request %p state change from %s to %s\n",
- (void *)req, names[req->state], names[newstate]);
+ (void *)req, names[req->state], names[newstate]);
#endif
req->state = newstate;
if(smbc->got < sizeof(unsigned int))
return CURLE_OK;
- nbt_size = Curl_read16_be((unsigned char *)(buf + sizeof(unsigned short))) +
- sizeof(unsigned int);
+ nbt_size = Curl_read16_be((const unsigned char *)
+ (buf + sizeof(unsigned short))) +
+ sizeof(unsigned int);
if(smbc->got < nbt_size)
return CURLE_OK;
if(nbt_size >= msg_size + sizeof(unsigned short)) {
/* Add the byte count */
msg_size += sizeof(unsigned short) +
- Curl_read16_le((unsigned char *)&buf[msg_size]);
+ Curl_read16_le((const unsigned char *)&buf[msg_size]);
if(nbt_size < msg_size)
return CURLE_READ_ERROR;
}
/* Check if there is data in the transfer buffer */
if(!smbc->send_size && smbc->upload_size) {
int nread = smbc->upload_size > BUFSIZE ? BUFSIZE :
- (int) smbc->upload_size;
+ (int) smbc->upload_size;
conn->data->req.upload_fromhere = conn->data->state.uploadbuffer;
result = Curl_fillreadbuffer(conn, nread, &nread);
if(result && result != CURLE_AGAIN)
switch(smbc->state) {
case SMB_NEGOTIATE:
- if(h->status) {
+ if(h->status || smbc->got < sizeof(*nrsp) + sizeof(smbc->challenge) - 1) {
connclose(conn, "SMB: negotiation failed");
return CURLE_COULDNT_CONNECT;
}
{
struct smb_request *req = conn->data->req.protop;
struct smb_header *h;
+ struct smb_conn *smbc = &conn->proto.smbc;
enum smb_req_state next_state = SMB_DONE;
unsigned short len;
unsigned short off;
break;
case SMB_OPEN:
- if(h->status) {
+ if(h->status || smbc->got < sizeof(struct smb_nt_create_response)) {
req->result = CURLE_REMOTE_FILE_NOT_FOUND;
next_state = SMB_TREE_DISCONNECT;
break;
break;
case SMB_DOWNLOAD:
- if(h->status) {
+ if(h->status || smbc->got < sizeof(struct smb_header) + 14) {
req->result = CURLE_RECV_ERROR;
next_state = SMB_CLOSE;
break;
}
- len = Curl_read16_le(((unsigned char *) msg) +
+ len = Curl_read16_le(((const unsigned char *) msg) +
sizeof(struct smb_header) + 11);
- off = Curl_read16_le(((unsigned char *) msg) +
+ off = Curl_read16_le(((const unsigned char *) msg) +
sizeof(struct smb_header) + 13);
if(len > 0) {
- struct smb_conn *smbc = &conn->proto.smbc;
if(off + sizeof(unsigned int) + len > smbc->got) {
failf(conn->data, "Invalid input packet");
result = CURLE_RECV_ERROR;
break;
case SMB_UPLOAD:
- if(h->status) {
+ if(h->status || smbc->got < sizeof(struct smb_header) + 6) {
req->result = CURLE_UPLOAD_FAILED;
next_state = SMB_CLOSE;
break;
}
- len = Curl_read16_le(((unsigned char *) msg) +
+ len = Curl_read16_le(((const unsigned char *) msg) +
sizeof(struct smb_header) + 5);
conn->data->req.bytecount += len;
conn->data->req.offset += len;