浏览代码

Make smb_find work. (Unicode conversion, TRANS2 message concatenation, session_setup max_buffer fix

Julien 'Lta' BALLET 11 年之前
父节点
当前提交
992d66540d
共有 8 个文件被更改,包括 97 次插入39 次删除
  1. 15 18
      bin/dsm.c
  2. 1 0
      include/bdsm/smb_message.h
  3. 2 0
      include/bdsm/smb_packets.h
  4. 19 0
      src/smb_message.c
  5. 3 1
      src/smb_session.c
  6. 1 1
      src/smb_share.c
  7. 47 19
      src/smb_trans2.c
  8. 9 0
      src/smb_utils.c

+ 15 - 18
bin/dsm.c

@@ -149,20 +149,18 @@ int main(int ac, char **av)
     else
       printf("Successfully logged in as %s\\%s\n", host, login);
   }
-  else
+  else if (smb_session_login(session, "WORKGROUP", login, password))
   {
-    printf("Authentication FAILURE.\n");
-    exit(42);
+    if (session->guest)
+      printf("Login FAILED but we were logged in as GUEST \n");
+    else
+      printf("Successfully logged in as %s\\%s\n", host, login);
   }
-
-  smb_tid ipc  = smb_tree_connect(session, "IPC$");
-
-  if (ipc == 0)
+  else
   {
-    fprintf(stderr, "Unable to connect to IPC$ share\n");
+    printf("Authentication FAILURE.\n");
     exit(42);
   }
-  fprintf(stderr, "Connected to IPC$ share\n");
 
   smb_tid test = smb_tree_connect(session, "test");
   if (test)
@@ -196,19 +194,18 @@ int main(int ac, char **av)
     fprintf(stderr, "Unable to list share for %s\n", host);
     exit(42);
   }
-  else
-  {
-    fprintf(stderr, "Share list : \n");
-    for (size_t j; share_list[j] != NULL; j++)
-      fprintf(stderr, "- %s\n", share_list[j]);
-  }
+
+  fprintf(stderr, "Share list : \n");
+  for (size_t j = 0; share_list[j] != NULL; j++)
+    fprintf(stderr, "- %s\n", share_list[j]);
+  smb_share_list_destroy(share_list);
 
   fprintf(stderr, "Let's find files at share's root :\n");
   files = smb_find(session, test, "\\*");
   if (files != NULL)
     while(files)
     {
-      fprintf(stderr, "Found a file %s \n", files->name);
+      fprintf(stdout, "Found a file %s \n", files->name);
       files = files->next;
     }
   else
@@ -217,8 +214,8 @@ int main(int ac, char **av)
   fprintf(stderr, "Query file info for path: %s\n", fname);
   files = smb_stat(session, test, fname);
 
-  if (files)
-    printf("File %s is %lu bytes long\n", fname, files->size);
+  if (files != NULL)
+    printf("File '%s' is %lu bytes long\n", fname, files->size);
 
 
   smb_session_destroy(session);

+ 1 - 0
include/bdsm/smb_message.h

@@ -31,6 +31,7 @@ typedef struct
 }                               smb_message_t;
 
 smb_message_t   *smb_message_new(uint8_t cmd, size_t payload_size);
+smb_message_t   *smb_message_grow(smb_message_t *msg, size_t size);
 void            smb_message_destroy(smb_message_t *msg);
 int             smb_message_advance(smb_message_t *msg, size_t size);
 int             smb_message_append(smb_message_t *msg, const void *data,

+ 2 - 0
include/bdsm/smb_packets.h

@@ -364,11 +364,13 @@ typedef struct
   uint64_t      written;
   uint64_t      changed;
   uint32_t      attr;
+  uint32_t      reserved;
   uint64_t      alloc_size;
   uint64_t      size;
   uint32_t      link_count;
   uint8_t       rm_pending;
   uint8_t       is_dir;
+  uint16_t      reserved2;
   uint32_t      ea_list_len;
   uint32_t      name_len;
   uint8_t       name[];

+ 19 - 0
src/smb_message.c

@@ -48,6 +48,25 @@ smb_message_t   *smb_message_new(uint8_t cmd, size_t payload_size)
   return (msg);
 }
 
+// Duplicate a message while growing payload_size.
+smb_message_t   *smb_message_grow(smb_message_t *msg, size_t size)
+{
+  smb_message_t *copy;
+
+  assert(msg != NULL && msg->packet != NULL);
+
+  copy = malloc(sizeof(smb_message_t));
+  assert(copy != NULL);
+  copy->cursor        = msg->cursor;
+  copy->payload_size  = msg->payload_size + size;
+
+  copy->packet = malloc(sizeof(smb_packet_t) + copy->payload_size);
+  assert(copy->packet != NULL);
+  memcpy((void *)copy->packet, (void *)msg->packet, msg->payload_size);
+
+  return (copy);
+}
+
 void            smb_message_destroy(smb_message_t *msg)
 {
   if (msg != NULL)

+ 3 - 1
src/smb_session.c

@@ -202,7 +202,9 @@ int             smb_session_login(smb_session_t *s, const char *domain,
   req = (smb_session_req_t *)msg->packet->payload;
 
   req->wct              = (sizeof(smb_session_req_t) - 3) / 2;
-  req->max_buffer       = NETBIOS_SESSION_PAYLOAD;
+  req->max_buffer       = NETBIOS_SESSION_PAYLOAD
+                          - sizeof(smb_header_t)
+                          - sizeof(netbios_session_packet_t);
   req->max_buffer      -= sizeof(netbios_session_packet_t);
   req->max_buffer      -= sizeof(smb_packet_t);
   req->mpx_count        = 16; // XXX ?

+ 1 - 1
src/smb_share.c

@@ -141,7 +141,7 @@ void            smb_share_list_destroy(char **list)
 {
   assert(list != NULL);
 
-  for (size_t i; list[i] != NULL; i++)
+  for (size_t i = 0; list[i] != NULL; i++)
     free(list[i]);
   free(list);
 }

+ 47 - 19
src/smb_trans2.c

@@ -22,6 +22,7 @@
 #include <assert.h>
 
 #include "bdsm/debug.h"
+#include "bdsm/smb_utils.h"
 #include "bdsm/smb_trans2.h"
 
 static smb_file_t *smb_find_parse(smb_message_t *msg)
@@ -41,18 +42,16 @@ static smb_file_t *smb_find_parse(smb_message_t *msg)
   iter    = (smb_tr2_find2_entry_t *)(tr2->payload + sizeof(smb_tr2_find2_params_t));
   eod     = msg->packet->payload + msg->payload_size;
   count   = params->count;
-  files   = tmp = NULL;
+  files   = NULL;
 
-  for(i = 0; i < count && (uint8_t *)iter < eod; i++)
+  for(i = 0; (uint8_t *)iter < eod; i++)
   {
+    // Create a smb_file_t and fill it
     tmp = calloc(1, sizeof(smb_file_t));
     assert(tmp != NULL);
 
-    tmp->name_len = iter->name_len + 2;
-    tmp->name     = malloc(tmp->name_len);
-    assert(tmp->name != NULL);
-    memcpy(tmp->name, iter->name, tmp->name_len - 2);
-    tmp->name[tmp->name_len - 1] = tmp->name[tmp->name_len - 2] = 0;
+    tmp->name_len = smb_from_utf16(iter->name, iter->name_len, &tmp->name);
+    tmp->name[tmp->name_len] = 0;
 
     tmp->created    = iter->created;
     tmp->accessed   = iter->accessed;
@@ -72,13 +71,48 @@ static smb_file_t *smb_find_parse(smb_message_t *msg)
   return (files);
 }
 
+static smb_message_t *smb_tr2_recv(smb_session_t *s)
+{
+  smb_message_t           recv, *res;
+  smb_trans2_resp_t       *tr2;
+  smb_tr2_find2_params_t  *params;
+  uint8_t                 *data;
+  size_t                  growth;
+  int                     remaining;
+
+  if (!smb_session_recv_msg(s, &recv))
+    return (NULL);
+
+  tr2         = (smb_trans2_resp_t *)recv.packet->payload;
+  growth      = tr2->total_data_count - tr2->data_count;
+  res         = smb_message_grow(&recv, growth);
+  res->cursor = recv.payload_size;
+  remaining   = (int)tr2->total_data_count -
+                (tr2->data_displacement + tr2->data_count);
+
+  while(remaining > 0)
+  {
+    remaining = smb_session_recv_msg(s, &recv);
+    if (remaining)
+    {
+      tr2   = (smb_trans2_resp_t *)recv.packet->payload;
+      smb_message_append(res, tr2->payload + 2 /*pad*/, tr2->data_count);
+      remaining = (int)tr2->total_data_count -
+                  (tr2->data_displacement + tr2->data_count);
+    }
+  }
+
+  return (res);
+}
+
 smb_file_t  *smb_find(smb_session_t *s, smb_tid tid, const char *pattern)
 {
   smb_message_t           *msg, reply;
   smb_trans2_req_t        *tr2;
   smb_tr2_find2_t         *find;
+  smb_file_t              *files, *tmp;
   size_t                  pattern_len, msg_len;
-  int                     res;
+  int                     res, recv_res;
 
   assert(s != NULL && pattern != NULL && tid);
 
@@ -125,14 +159,10 @@ smb_file_t  *smb_find(smb_session_t *s, smb_tid tid, const char *pattern)
     return (NULL);
   }
 
-  if (!smb_session_recv_msg(s, &reply)
-      || reply.packet->header.status != NT_STATUS_SUCCESS)
-  {
-    BDSM_dbg("Unable to recv msg or failure for %s\n", pattern);
+  if ((msg = smb_tr2_recv(s)) == NULL)
     return (NULL);
-  }
 
-  return (smb_find_parse(&reply));
+  return (smb_find_parse(msg));
 }
 
 
@@ -202,14 +232,12 @@ smb_file_t  *smb_stat(smb_session_t *s, smb_tid tid, const char *path)
   }
 
   tr2_resp  = (smb_trans2_resp_t *)reply.packet->payload;
-  info      = (smb_tr2_path_info_t *)tr2_resp->payload;
+  info      = (smb_tr2_path_info_t *)(tr2_resp->payload + 4); //+4 is padding
   file      = calloc(1, sizeof(smb_file_t));
   assert(file != NULL);
 
-  file->name_len  = info->name_len;
-  file->name      = malloc(info->name_len);
-  assert(file->name != NULL);
-  memcpy(file->name, info->name, file->name_len);
+  file->name_len  = smb_from_utf16(info->name, info->name_len, &file->name);
+  file->name[info->name_len] = 0;
 
   file->created     = info->created;
   file->accessed    = info->accessed;

+ 9 - 0
src/smb_utils.c

@@ -18,6 +18,7 @@
 
 #include <assert.h>
 #include <iconv.h>
+#include <locale.h>
 #include <langinfo.h>
 #include <stdio.h>
 #include <stdlib.h>
@@ -27,6 +28,14 @@
 
 static const char *current_encoding()
 {
+  static int locale_set = 0;
+
+  if (!locale_set)
+  {
+    setlocale(LC_ALL, "");
+    locale_set = 1;
+  }
+  //fprintf(stderr, "%s\n", nl_langinfo(CODESET));
   return (nl_langinfo(CODESET));
 }