浏览代码

Split packets format code to its own header file. '''Implement''' the first stage of server share listing

Julien 'Lta' BALLET 11 年之前
父节点
当前提交
61609b0e6e
共有 12 个文件被更改,包括 476 次插入244 次删除
  1. 13 13
      Makefile
  2. 21 9
      dsm.c
  3. 2 213
      include/bdsm/smb_defs.h
  4. 1 1
      include/bdsm/smb_file.h
  5. 3 1
      include/bdsm/smb_message.h
  6. 275 0
      include/bdsm/smb_packets.h
  7. 8 2
      include/bdsm/smb_session.h
  8. 8 1
      include/bdsm/smb_share.h
  9. 1 0
      src/smb_file.c
  10. 19 1
      src/smb_message.c
  11. 1 0
      src/smb_session.c
  12. 124 3
      src/smb_share.c

+ 13 - 13
Makefile

@@ -14,7 +14,7 @@
 ## permitted by applicable law. You can redistribute it and/or modify it under
 ## the terms of the Do What The Fuck You Want To Public License, Version 2, as
 ## published by Sam Hocevar. See the COPYING file for more details.
-	##----------------------------------------------------------------------------
+##----------------------------------------------------------------------------
 
 
 
@@ -26,18 +26,18 @@ UTIL				= dsm
 LIB					= libdsm.so
 
 UTIL_SRC		= dsm.c 							    \
-							src/netbios_utils.c	    \
-							src/netbios_ns.c		    \
-							src/netbios_ns_entry.c	\
-							src/netbios_query.c     \
-							src/netbios_session.c		\
-							src/smb_utils.c					\
-							src/smb_message.c				\
-							src/smb_session.c				\
-							src/smb_ntlm.c					\
-							src/smb_share.c					\
-							src/smb_file.c					\
-							src/context.c
+			src/netbios_utils.c				\
+			src/netbios_ns.c				\
+			src/netbios_ns_entry.c				\
+			src/netbios_query.c				\
+			src/netbios_session.c				\
+			src/smb_utils.c					\
+			src/smb_message.c				\
+			src/smb_session.c				\
+			src/smb_ntlm.c					\
+			src/smb_share.c					\
+			src/smb_file.c					\
+			src/context.c
 
 UTIL_OBJS		= $(UTIL_SRC:.c=.o)
 

+ 21 - 9
dsm.c

@@ -21,6 +21,8 @@
 #include <string.h>
 #include <assert.h>
 #include <unistd.h>
+#include <sys/stat.h>
+#include <fcntl.h>
 #include <errno.h>
 
 #include <sys/socket.h>
@@ -97,7 +99,7 @@ int main(int ac, char **av)
     exit(42);
   }
 
-  smb_tid ipc  = smb_tree_connect(session, "\\\\CERBERE\\IPC$");
+  smb_tid ipc  = smb_tree_connect(session, "IPC$");
 
   if (ipc == 0)
   {
@@ -106,7 +108,7 @@ int main(int ac, char **av)
   }
   fprintf(stderr, "Connected to IPC$ share\n");
 
-  smb_tid test = smb_tree_connect(session, "\\\\CERBERE\\TEST");
+  smb_tid test = smb_tree_connect(session, "TEST");
   if (test)
     fprintf(stderr, "Connected to Test share\n");
   else
@@ -115,24 +117,34 @@ int main(int ac, char **av)
     exit(42);
   }
 
-  smb_fd fd = smb_fopen(session, test, "\\test.txt", SMB_MOD_RO);
+  smb_fd fd = smb_fopen(session, test, "\\test.avi", SMB_MOD_RO);
   if (fd)
-    fprintf(stderr, "Successfully opened \\test.txt: fd = 0x%.8x\n", fd);
+    fprintf(stderr, "Successfully opened \\test.avi: fd = 0x%.8x\n", fd);
   else
   {
-    fprintf(stderr, "Unable to open \\test.txt\n");
+    fprintf(stderr, "Unable to open \\test.avi\n");
     exit(42);
   }
 
-  char    data[512];
+  char              data[1024];
+  smb_share_list_t  *share_list;
 
-  memset(data, 0, 512);
-  smb_fread(session, fd, data, 512);
 
+  smb_fread(session, fd, data, 1024);
   fprintf(stderr, "Read from file:\n%s\n", data);
-
   smb_fclose(session, fd);
 
+  if (!smb_share_list(session, &share_list))
+  {
+    fprintf(stderr, "Unable to list share for %s\n", av[1]);
+    exit(42);
+  }
+  else
+  {
+    fprintf(stderr, "Share list : \n");
+  }
+
+
   smb_session_destroy(session);
   bdsm_context_destroy(ctx);
 

+ 2 - 213
include/bdsm/smb_defs.h

@@ -19,7 +19,7 @@
 #ifndef __BSDM_SMB_DEFS_H_
 #define __BSDM_SMB_DEFS_H_
 
-#include <stdint.h>
+#include <bdsm/smb_packets.h>
 
 #define SMB_MAGIC               { 0xff, 0x53, 0x4d, 0x42 } // aka "\xffSMB"
 
@@ -34,6 +34,7 @@
 #define SMB_DIALECT_NTLM        1
 
 #define SMB_CMD_CLOSE           0x04
+#define SMD_CMD_TRANS           0x25
 #define SMB_CMD_TRANS2          0x32
 #define SMB_CMD_TREE_DISCONNECT 0x71
 #define SMB_CMD_NEGOTIATE       0x72
@@ -139,217 +140,5 @@
 #define NT_STATUS_MORE_PROCESSING_REQUIRED  0xc0000016
 #define NT_STATUS_ACCESS_DENIED             0xc0000022
 
-#define SMB_ANDX_MEMBERS  \
-  uint8_t         andx;           /* 0xff when no other command (do this :)*/  \
-  uint8_t         andx_reserved;  /* 0x00 */                                   \
-  uint16_t        andx_offset;    /* 0x00 when no other command */
-
-
-////////////////////////////////////////////////////////////////////////////////
-// Individual SMB command payload description
-
-
-//// Negotiate Protocol
-
-typedef struct
-{
-  uint8_t         wct; // zero
-  uint16_t        bct;
-  char            dialects[];
-
-} __attribute__((packed))   smb_negotiate_req_t;
-
-typedef struct
-{
-  uint8_t         wct;            // +-17 :)
-  uint16_t        dialect_index;  //
-  uint8_t         security_mode;  // Share/User. Plaintext/Challenge
-  uint32_t        diplodocus;
-  uint32_t        max_bufsize;    // Max buffer size requested by server.
-  uint32_t        max_rawbuffer;  // Max raw buffer size requested by serv.
-  uint32_t        session_key;    // 'MUST' be returned to server
-  uint32_t        caps;
-  uint64_t        ts;             // I don't give a fuck (or do i?)
-  uint16_t        tz;             // Even less fuck given
-  uint8_t         key_length;     // Size of challenge key, if != 8 then shit
-  uint16_t        bct;
-  uint64_t        challenge;      // Normally 8 bytes, if not then wtf monkey
-  uint8_t         payload[];      // The rest isn't really meaningfull for us
-} __attribute__((packed))   smb_negotiate_resp_t;
-
-
-
-//// Session Setup
-
-typedef struct
-{
-  uint8_t         wct;          // +-13 :)
-  SMB_ANDX_MEMBERS
-  uint16_t        max_buffer;   // Maximum size we can receive
-  uint16_t        mpx_count;    // maximum multiplexed session
-  uint16_t        vc_count;     // Virtual ciruits -> 1!
-  uint32_t        session_key;  // 0x00000000
-  uint16_t        oem_pass_len; // Length of LM2 response
-  uint16_t        uni_pass_len; // Length of NTLM2 response
-  uint32_t        reserved2;    // 0x00000000
-  uint32_t        caps;         // Capabilities
-  uint16_t        payload_size;
-  uint8_t         payload[];
-} __attribute__((packed))   smb_session_req_t;
-
-typedef struct
-{
-  uint8_t         wct;
-  SMB_ANDX_MEMBERS
-  uint16_t        action;
-  uint16_t        bct;
-  uint8_t         bullshit[];
-} __attribute__((packed))   smb_session_resp_t;
-
-
-
-//// Tree Connect
-
-typedef struct
-{
-  uint8_t         wct;              // 4
-  SMB_ANDX_MEMBERS
-  uint16_t        flags;
-  uint16_t        passwd_len;       // 1 if not used. Used in Share Level Auth
-  uint16_t        bct;
-  uint8_t         payload[];        // Password | Path | Service
-
-} __attribute__((packed))   smb_tree_connect_req_t;
-
-typedef struct
-{
-  uint8_t         wct;              // 7
-  SMB_ANDX_MEMBERS
-  uint16_t        opt_support;
-  uint32_t        max_rights;
-  uint32_t        guest_rights;
-  uint16_t        bct;
-  uint8_t         payload[];
-} __attribute__((packed))   smb_tree_connect_resp_t;
-
-
-
-//// Create (or Open) File
-
-typedef struct
-{
-  uint8_t         wct;                // 24
-  SMB_ANDX_MEMBERS
-  uint8_t         reserved2;
-  uint16_t        path_length;
-  uint32_t        flags;
-  uint32_t        root_fid;
-  uint32_t        access_mask;
-  uint64_t        alloc_size;
-  uint32_t        file_attr;
-  uint32_t        share_access;
-  uint32_t        disposition;
-  uint32_t        create_opts;
-  uint32_t        impersonation;
-  uint8_t         security_flags;
-  uint16_t        bct;
-  uint8_t         path[];             // UTF16 Path, starting with '\'
-} __attribute__((packed))   smb_create_req_t;
-
-typedef struct
-{
-  uint8_t         wct;                // 34
-  SMB_ANDX_MEMBERS
-  uint8_t         oplock_level;
-  uint16_t        fid;
-  uint32_t        action;
-  uint64_t        created;            // File creation time
-  uint64_t        accessed;           // File last access time
-  uint64_t        written;            // File last write time
-  uint64_t        changed;            // File last modification time
-  uint32_t        attr;
-  uint64_t        alloc_size;
-  uint64_t        size;
-  uint16_t        filetype;
-  uint16_t        ipc_state;
-  uint8_t         is_dir;
-  uint16_t        bct;                // 0
-} __attribute__((packed))   smb_create_resp_t;
-
-
-
-//// Close File
-
-typedef struct
-{
-  uint8_t         wct;                // 3
-  uint16_t        fid;
-  uint32_t        last_write;         // Not defined == 0xffffffff
-  uint16_t        bct;                // 0
-} __attribute__((packed))   smb_close_req_t;
-
-
-
-//// Read File
-
-typedef struct
-{
-  uint8_t         wct;                // 12
-  SMB_ANDX_MEMBERS
-  uint16_t        fid;
-  uint32_t        offset;
-  uint16_t        max_count;
-  uint16_t        min_count;
-  uint32_t        max_count_high;     // Continuation of max_count field
-  uint16_t        remaining;
-  uint32_t        offset_high;        // Continuation of offset field'
-  uint16_t        bct;                // 0
-} __attribute__((packed))   smb_read_req_t;
-
-typedef struct
-{
-  uint8_t         wct;                // 12
-  SMB_ANDX_MEMBERS
-  uint16_t        remaining;
-  uint16_t        compact_mode;
-  uint16_t        reserved;
-  uint16_t        data_len;
-  uint16_t        data_offset;
-  uint32_t        data_len_high;
-  uint32_t        reserved2;
-  uint16_t        reserved3;
-  uint16_t        bct;
-  uint8_t         padding;
-  uint8_t         file[];
-} __attribute__((packed))   smb_read_resp_t;
-
-
-
-
-////////////////////////////////////////////////////////////////////////////////
-// Main structures for holding packet data and building packets
-
-typedef struct
-{
-  uint8_t         magic[4];     // { 0xff, 0x53, 0x4d, 0x42 } "\xffSMB"
-  uint8_t         command;      // The actual SMB command
-  uint32_t        status;       // 'NT Status'
-  uint8_t         flags;        // Packet flags
-  uint16_t        flags2;       // More flags ? (lol)
-  uint16_t        pid_high;     // Unused ?
-  uint64_t        signature;    // Unused ?
-  uint16_t        reserved;     // More usuned bit (we have so much BW :)
-  uint16_t        tid;          // A kind of fd for share. (tree_connect)
-  uint16_t        pid;          // Process ID.
-  uint16_t        uid;          // User ID.
-  uint16_t        mux_id;       // Multiplex ID. Increment it sometimes.
-} __attribute__((packed))       smb_header_t;
-
-typedef struct
-{
-  smb_header_t    header;       // A packet header full of gorgeous goodness.
-  uint8_t         payload[];    // Ze yummy data inside. Eat 5 fruits/day !
-} __attribute__((packed))       smb_packet_t;
-
 
 #endif

+ 1 - 1
include/bdsm/smb_file.h

@@ -22,7 +22,7 @@
 #include "bdsm/smb_session.h"
 
 smb_fd    smb_fopen(smb_session_t *s, smb_tid tid, const char *path,
-                   uint32_t mod);
+                    uint32_t mod);
 void      smb_fclose(smb_session_t *s, smb_fd);
 ssize_t   smb_fread(smb_session_t *s, smb_fd fd, void *buf, size_t buf_size);
 ssize_t   smb_fseek(smb_session_t *s, smb_fd fd, ssize_t offset, int whence);

+ 3 - 1
include/bdsm/smb_message.h

@@ -38,9 +38,11 @@ int             smb_message_append(smb_message_t *msg, const void *data,
 int             smb_message_put8(smb_message_t *msg, uint8_t data);
 int             smb_message_put16(smb_message_t *msg, uint16_t data);
 int             smb_message_put32(smb_message_t *msg, uint32_t data);
-int             smb_message_put64(smb_message_t *msg, uint32_t data);
+int             smb_message_put64(smb_message_t *msg, uint64_t data);
 size_t          smb_message_put_utf16(smb_message_t *msg, const char *src_enc,
                                       const char *str, size_t str_len);
+int             smb_message_put_uuid(smb_message_t *msg, uint32_t a, uint16_t b,
+                                     uint16_t c, const uint8_t e[8]);
 
 void            smb_message_set_default_flags(smb_message_t *msg);
 void            smb_message_set_andx_members(smb_message_t *msg);

+ 275 - 0
include/bdsm/smb_packets.h

@@ -0,0 +1,275 @@
+//---------------------------------------------------------------------------
+//  __________________    _________  _____            _____  .__         ._.
+//  \______   \______ \  /   _____/ /     \          /  _  \ |__| ____   | |
+//   |    |  _/|    |  \ \_____  \ /  \ /  \        /  /_\  \|  _/ __ \  | |
+//   |    |   \|    `   \/        /    Y    \      /    |    |  \  ___/   \|
+//   |______  /_______  /_______  \____|__  / /\   \____|__  |__|\___ |   __
+//          \/        \/        \/        \/  )/           \/        \/   \/
+//
+// This file is part of libdsm. Copyright © 2014 VideoLabs SAS
+//
+// Author: Julien 'Lta' BALLET <contact@lta.io>
+//
+// This program is free software. It comes without any warranty, to the extent
+// permitted by applicable law. You can redistribute it and/or modify it under
+// the terms of the Do What The Fuck You Want To Public License, Version 2, as
+// published by Sam Hocevar. See the COPYING file for more details.
+//----------------------------------------------------------------------------
+
+#ifndef __BSDM_SMB_PACKETS_H_
+#define __BSDM_SMB_PACKETS_H_
+
+#include <stdint.h>
+
+#define SMB_ANDX_MEMBERS  \
+  uint8_t         andx;           /* 0xff when no other command (do this :)*/  \
+  uint8_t         andx_reserved;  /* 0x00 */                                   \
+  uint16_t        andx_offset;    /* 0x00 when no other command */
+
+
+////////////////////////////////////////////////////////////////////////////////
+// Main structures for holding packet data and building packets
+
+typedef struct
+{
+  uint8_t         magic[4];     // { 0xff, 0x53, 0x4d, 0x42 } "\xffSMB"
+  uint8_t         command;      // The actual SMB command
+  uint32_t        status;       // 'NT Status'
+  uint8_t         flags;        // Packet flags
+  uint16_t        flags2;       // More flags ? (lol)
+  uint16_t        pid_high;     // Unused ?
+  uint64_t        signature;    // Unused ?
+  uint16_t        reserved;     // More usuned bit (we have so much BW :)
+  uint16_t        tid;          // A kind of fd for share. (tree_connect)
+  uint16_t        pid;          // Process ID.
+  uint16_t        uid;          // User ID.
+  uint16_t        mux_id;       // Multiplex ID. Increment it sometimes.
+} __attribute__((packed))       smb_header_t;
+
+typedef struct
+{
+  smb_header_t    header;       // A packet header full of gorgeous goodness.
+  uint8_t         payload[];    // Ze yummy data inside. Eat 5 fruits/day !
+} __attribute__((packed))       smb_packet_t;
+
+
+////////////////////////////////////////////////////////////////////////////////
+// Individual SMB command payload description
+
+//-> Negotiate Protocol
+typedef struct
+{
+  uint8_t         wct; // zero
+  uint16_t        bct;
+  char            dialects[];
+
+} __attribute__((packed))   smb_negotiate_req_t;
+
+//<- Negotiate Protocol
+typedef struct
+{
+  uint8_t         wct;            // +-17 :)
+  uint16_t        dialect_index;  //
+  uint8_t         security_mode;  // Share/User. Plaintext/Challenge
+  uint32_t        diplodocus;
+  uint32_t        max_bufsize;    // Max buffer size requested by server.
+  uint32_t        max_rawbuffer;  // Max raw buffer size requested by serv.
+  uint32_t        session_key;    // 'MUST' be returned to server
+  uint32_t        caps;
+  uint64_t        ts;             // I don't give a fuck (or do i?)
+  uint16_t        tz;             // Even less fuck given
+  uint8_t         key_length;     // Size of challenge key, if != 8 then shit
+  uint16_t        bct;
+  uint64_t        challenge;      // Normally 8 bytes, if not then wtf monkey
+  uint8_t         payload[];      // The rest isn't really meaningfull for us
+} __attribute__((packed))   smb_negotiate_resp_t;
+
+
+
+//-> Session Setup
+typedef struct
+{
+  uint8_t         wct;          // +-13 :)
+  SMB_ANDX_MEMBERS
+  uint16_t        max_buffer;   // Maximum size we can receive
+  uint16_t        mpx_count;    // maximum multiplexed session
+  uint16_t        vc_count;     // Virtual ciruits -> 1!
+
+  uint32_t        session_key;  // 0x00000000
+  uint16_t        oem_pass_len; // Length of LM2 response
+  uint16_t        uni_pass_len; // Length of NTLM2 response
+  uint32_t        reserved2;    // 0x00000000
+  uint32_t        caps;         // Capabilities
+  uint16_t        payload_size;
+  uint8_t         payload[];
+} __attribute__((packed))   smb_session_req_t;
+
+//<- Session Setup
+typedef struct
+{
+  uint8_t         wct;
+  SMB_ANDX_MEMBERS
+  uint16_t        action;
+  uint16_t        bct;
+  uint8_t         bullshit[];
+} __attribute__((packed))   smb_session_resp_t;
+
+
+
+//-> Tree Connect
+typedef struct
+{
+  uint8_t         wct;              // 4
+  SMB_ANDX_MEMBERS
+  uint16_t        flags;
+  uint16_t        passwd_len;       // 1 if not used. Used in Share Level Auth
+  uint16_t        bct;
+  uint8_t         payload[];        // Password | Path | Service
+
+} __attribute__((packed))   smb_tree_connect_req_t;
+
+//<- Tree Connect
+typedef struct
+{
+  uint8_t         wct;              // 7
+  SMB_ANDX_MEMBERS
+  uint16_t        opt_support;
+  uint32_t        max_rights;
+  uint32_t        guest_rights;
+  uint16_t        bct;
+  uint8_t         payload[];
+} __attribute__((packed))   smb_tree_connect_resp_t;
+
+
+
+//-> Create File
+typedef struct
+{
+  uint8_t         wct;                // 24
+  SMB_ANDX_MEMBERS
+  uint8_t         reserved2;
+  uint16_t        path_length;
+  uint32_t        flags;
+  uint32_t        root_fid;
+  uint32_t        access_mask;
+  uint64_t        alloc_size;
+  uint32_t        file_attr;
+  uint32_t        share_access;
+  uint32_t        disposition;
+  uint32_t        create_opts;
+  uint32_t        impersonation;
+  uint8_t         security_flags;
+  uint16_t        bct;
+  uint8_t         path[];             // UTF16 Path, starting with '\'
+} __attribute__((packed))   smb_create_req_t;
+
+//<- Create File
+typedef struct
+{
+  uint8_t         wct;                // 34
+  SMB_ANDX_MEMBERS
+  uint8_t         oplock_level;
+  uint16_t        fid;
+  uint32_t        action;
+  uint64_t        created;            // File creation time
+  uint64_t        accessed;           // File last access time
+  uint64_t        written;            // File last write time
+  uint64_t        changed;            // File last modification time
+  uint32_t        attr;
+  uint64_t        alloc_size;
+  uint64_t        size;
+  uint16_t        filetype;
+  uint16_t        ipc_state;
+  uint8_t         is_dir;
+  uint16_t        bct;                // 0
+} __attribute__((packed))   smb_create_resp_t;
+
+
+
+//-> Close File
+typedef struct
+{
+  uint8_t         wct;                // 3
+  uint16_t        fid;
+  uint32_t        last_write;         // Not defined == 0xffffffff
+  uint16_t        bct;                // 0
+} __attribute__((packed))   smb_close_req_t;
+
+
+
+//-> Read File
+typedef struct
+{
+  uint8_t         wct;                // 12
+  SMB_ANDX_MEMBERS
+  uint16_t        fid;
+  uint32_t        offset;
+  uint16_t        max_count;
+  uint16_t        min_count;
+  uint32_t        max_count_high;     // Continuation of max_count field
+  uint16_t        remaining;
+  uint32_t        offset_high;        // Continuation of offset field'
+  uint16_t        bct;                // 0
+} __attribute__((packed))   smb_read_req_t;
+
+//<- Read File
+typedef struct
+{
+  uint8_t         wct;                // 12
+  SMB_ANDX_MEMBERS
+  uint16_t        remaining;
+  uint16_t        compact_mode;
+  uint16_t        reserved;
+  uint16_t        data_len;
+  uint16_t        data_offset;
+  uint32_t        data_len_high;
+  uint32_t        reserved2;
+  uint16_t        reserved3;
+  uint16_t        bct;
+  uint8_t         padding;
+  uint8_t         file[];
+} __attribute__((packed))   smb_read_resp_t;
+
+//-> Trans
+typedef struct
+{
+  uint8_t       wct;                    // 16
+  uint16_t      total_param_count;
+  uint16_t      total_data_count;
+  uint16_t      max_param_count;
+  uint16_t      max_data_count;
+  uint8_t       max_setup_count;
+  uint8_t       reserved;
+  uint16_t      flags;
+  uint32_t      timeout;
+  uint16_t      reserved2;
+  uint16_t      param_count;
+  uint16_t      param_offset;
+  uint16_t      data_count;
+  uint16_t      data_offset;
+  uint8_t       setup_count;
+  uint8_t       reserved3;
+  uint16_t      pipe_function;
+  uint16_t      fid;
+  uint16_t      bct;
+  uint8_t       padding;
+  uint8_t       payload[];
+} __attribute__((packed))   smb_trans_req_t;
+
+
+
+
+
+//-> Example
+typedef struct
+{
+  uint8_t         wct;                // ??
+  SMB_ANDX_MEMBERS
+  // Fill me
+  uint16_t        bct;
+  //uint8_t         padding;
+  uint8_t         file[];
+} __attribute__((packed))   smb_example_t;
+
+
+#endif

+ 8 - 2
include/bdsm/smb_session.h

@@ -19,10 +19,12 @@
 #ifndef __BDSM_SMB_SESSION_H_
 #define __BDSM_SMB_SESSION_H_
 
+
 #include "bdsm/netbios_session.h"
 #include "bdsm/smb_defs.h"
 #include "bdsm/smb_message.h"
 
+
 #define SMB_STATE_SESSION_OK    3 // We are authenticated and can do stuff
 #define SMB_STATE_DIALECT_OK    2
 #define SMB_STATE_NETBIOS_OK    1
@@ -56,6 +58,7 @@ typedef struct smb_file_s
   uint64_t            size;
   uint32_t            attr;
   uint32_t            readp;          // Current read pointer (position);
+  int                 is_dir;         // 0 -> file, 1 -> directory
 } smb_file_t;
 
 typedef struct smb_share_s
@@ -65,7 +68,7 @@ typedef struct smb_share_s
   uint16_t            opts;           // Optionnal support opts
   uint16_t            rights;         // Maximum rights field
   uint16_t            guest_rights;
-  smb_file_t          *files;         // List of all open files for this share
+  struct smb_file_s   *files;         // List of all open files for this share
 } smb_share_t;
 
 typedef struct
@@ -77,6 +80,7 @@ typedef struct
 
   // Informations about the smb server we are connected to.
   struct {
+    char                name[16];       // The server name
     uint16_t            dialect;        // The selected dialect
     uint16_t            security_mode;  // Security mode
     uint32_t            caps;           // Server caps replyed during negotiate
@@ -85,10 +89,12 @@ typedef struct
     uint64_t            ts;             // It seems Win7 requires it :-/
   }                   srv;
 
-  smb_share_t         *shares;          // shares->files | Map fd <-> smb_file_t
+  struct smb_share_s  *shares;          // shares->files | Map fd <-> smb_file_t
 }                   smb_session_t;
 
 
+
+
 smb_session_t   *smb_session_new();
 void            smb_session_destroy(smb_session_t *s);
 

+ 8 - 1
include/bdsm/smb_share.h

@@ -20,8 +20,15 @@
 #define __BDSM_SMB_SHARE_H_
 
 #include "bdsm/smb_session.h"
+#include "bdsm/smb_file.h"
 
-smb_tid         smb_tree_connect(smb_session_t *s, const char *path);
+typedef struct  smb_share_list_s
+{
+  char                name[16];
+}               smb_share_list_t;
+
+size_t          smb_share_list(smb_session_t *s, smb_share_list_t **list);
+smb_tid         smb_tree_connect(smb_session_t *s, const char *name);
 int             smb_tree_disconnect(smb_session_t *s, smb_tid tid);
 
 #endif

+ 1 - 0
src/smb_file.c

@@ -92,6 +92,7 @@ smb_fd      smb_fopen(smb_session_t *s, smb_tid tid, const char *path,
   file->alloc_size    = resp->alloc_size;
   file->size          = resp->size;
   file->attr          = resp->attr;
+  file->is_dir        = resp->is_dir;
 
   smb_session_file_add(s, tid, file); // XXX Check return
 

+ 19 - 1
src/smb_message.c

@@ -100,7 +100,7 @@ int             smb_message_put32(smb_message_t *msg, uint32_t data)
     return(smb_message_append(msg, (void *)&data, 4));
 }
 
-int             smb_message_put64(smb_message_t *msg, uint32_t data)
+int             smb_message_put64(smb_message_t *msg, uint64_t data)
 {
     return(smb_message_append(msg, (void *)&data, 8));
 }
@@ -121,6 +121,24 @@ size_t          smb_message_put_utf16(smb_message_t *msg, const char *src_enc,
   return (0);
 }
 
+int             smb_message_put_uuid(smb_message_t *msg, uint32_t a, uint16_t b,
+                                     uint16_t c, const uint8_t d[8])
+{
+  assert(msg != NULL);
+
+  if (!smb_message_put32(msg, a))
+    return (0);
+  if (!smb_message_put16(msg, b))
+    return (0);
+  if (!smb_message_put16(msg, c))
+    return (0);
+  for (int i = 0; i < 8; i++)
+    if (!smb_message_put8(msg, d[i]))
+      return (0);
+
+  return (1);
+}
+
 void            smb_message_flag(smb_message_t *msg, uint32_t flag, int value)
 {
   uint32_t      *flags;

+ 1 - 0
src/smb_session.c

@@ -54,6 +54,7 @@ int             smb_session_connect(smb_session_t *s, char *name, uint32_t ip)
   if (!netbios_session_connect(s->nb_session, name))
     goto error;
 
+  memcpy(s->srv.name, name, strlen(name) + 1);
   s->state = SMB_STATE_NETBIOS_OK;
   return (1);
 

+ 124 - 3
src/smb_share.c

@@ -24,17 +24,25 @@
 
 #include "bdsm/smb_utils.h"
 #include "bdsm/smb_share.h"
+#include "bdsm/smb_file.h"
 
 
-smb_tid         smb_tree_connect(smb_session_t *s, const char *path)
+smb_tid         smb_tree_connect(smb_session_t *s, const char *name)
 {
   smb_tree_connect_req_t  *req;
   smb_tree_connect_resp_t *resp;
   smb_message_t   resp_msg;
   smb_message_t   *req_msg;
   smb_share_t     *share;
+  size_t          path_len;
+  char            *path;
 
-  assert(s != NULL && path != NULL);
+  assert(s != NULL && name != NULL);
+
+  // Build \\SERVER\Share path from name
+  path_len  = strlen(name) + strlen(s->srv.name) + 4;
+  path      = alloca(path_len);
+  snprintf(path, path_len, "\\\\%s\\%s", s->srv.name, name);
 
   req_msg = smb_message_new(SMB_CMD_TREE_CONNECT, 128);
 
@@ -84,7 +92,120 @@ smb_tid         smb_tree_connect(smb_session_t *s, const char *path)
 int           smb_tree_disconnect(smb_session_t *s, smb_tid tid)
 {
   assert(s != NULL && tid);
-
+  fprintf(stderr, "smb_tree_disconnect: NOT IMPLEMENTED YET\n");
   return (0);
 }
 
+// We should normally implement SCERPC and SRVSVC to perform a share list. But
+// since these two protocols have no other use for use, we'll do it the trash
+// way
+// PS: Worst function _EVER_. I don't understand a bit myself
+size_t          smb_share_list(smb_session_t *s, smb_share_list_t **list)
+{
+  smb_message_t         *req, resp;
+  smb_trans_req_t       *trans;
+  smb_tid               ipc_tid;
+  smb_fd                srvscv_fd;
+  uint16_t              rpc_len;
+  ssize_t               res;
+
+  assert(s != NULL && list != NULL);
+  *list = NULL;
+
+  ipc_tid = smb_tree_connect(s, "IPC$");
+  if (!ipc_tid)
+    return (0);
+
+  srvscv_fd = smb_fopen(s, ipc_tid, "\\srvsvc", SMB_MOD_RW);
+  if (!srvscv_fd)
+    return (0);
+
+  //// Phase 1:
+  // We bind a context or whatever for DCE/RPC
+
+  req = smb_message_new(SMD_CMD_TRANS, 256);
+  smb_message_set_default_flags(req);
+  req->packet->header.tid = ipc_tid;
+
+  smb_message_advance(req, sizeof(smb_trans_req_t));
+  trans = (smb_trans_req_t *)req->packet->payload;
+
+  memset((void *)trans, 0, sizeof(smb_trans_req_t));
+
+  rpc_len = NETBIOS_SESSION_PAYLOAD - 256; // XXX
+
+  trans->wct                    = 16;
+  trans->total_data_count       = 72;
+  trans->max_data_count         = rpc_len;
+  trans->param_offset           = 84;
+  trans->data_count             = 72;
+  trans->data_offset            = 84;
+  trans->setup_count            = 2;
+  trans->pipe_function          = 0x26;
+  trans->fid                    = SMB_FD_FID(srvscv_fd);
+  trans->bct                    = 89;
+
+  smb_message_put_utf16(req, "", "\\PIPE\\", strlen("\\PIPE\\") + 1);
+  smb_message_put16(req, 0); // Padding to be aligned with wtf boundary :-/
+
+  // Now we'll 'build' the DCE/RPC Packet. This basically a copycat
+  // from wireshark values.
+  smb_message_put8(req, 5);     // version major
+  smb_message_put8(req, 0);     // minor
+  smb_message_put8(req, 0x0b);  // Packet type = 'bind'
+  smb_message_put8(req, 0x03);  // Packet flags = ??
+  smb_message_put32(req, 0x10); // Representation = little endian/ASCII. Damn
+  smb_message_put16(req, 72);   // Data len again
+  smb_message_put16(req, 0);    // Auth len ?
+  smb_message_put32(req, 19);   // Call ID ?
+  smb_message_put16(req, rpc_len);      // Max Xmit size
+  smb_message_put16(req, rpc_len);      // Max Recv size
+  smb_message_put32(req, 0);    // Assoc group ?
+
+  smb_message_put32(req, 1);    // Num Ctx Item
+  // Adding the CtxItem, whatever could that be
+  smb_message_put16(req, 0);    // ContextID
+  smb_message_put16(req, 1);    // Num Trans Item
+  // SRVSVC UUID
+  const uint8_t uuid_e[8] = {0x12, 0x78, 0x5a, 0x47, 0xbf, 0x6e, 0xe1, 0x88};
+  smb_message_put_uuid(req, 0x4b324fc8, 0x1670, 0x01d3, uuid_e);
+  smb_message_put16(req, 3);    // Version
+  smb_message_put16(req, 0);    // Minor
+  // Another UUID
+  const uint8_t uuid_e2[8] = {0x9f, 0xe8, 0x08, 0x00, 0x2b, 0x10, 0x48, 0x60};
+  smb_message_put_uuid(req, 0x8a885d04, 0x1ceb, 0x11c9, uuid_e2);
+  smb_message_put32(req, 2);    // Another version
+
+  // Let's send this ugly pile of shit over the network !
+  res = smb_session_send_msg(s, req);
+  smb_message_destroy(req);
+  if (!res)
+    return (0);
+
+  // Is the server throwing pile of shit back at me ?
+  res = smb_session_recv_msg(s, &resp);
+  if (!res || resp.packet->payload[68])
+  {
+    if (BDSM_DEBUG)
+      fprintf(stderr, "Bind call failed: 0x%hhx (reason = 0x%hhx)\n",
+              resp.packet->payload[68], resp.packet->payload[70]);
+    return (0);
+  }
+
+
+  //// Phase 2:
+  // Now we have the 'bind' (regarless of what it is), we'll call
+  // NetShareEnumAll
+
+  req = smb_message_new(SMD_CMD_TRANS, 256);
+  smb_message_set_default_flags(req);
+  req->packet->header.tid = ipc_tid;
+
+  smb_message_advance(req, sizeof(smb_trans_req_t));
+  trans = (smb_trans_req_t *)req->packet->payload;
+
+  memset((void *)trans, 0, sizeof(smb_trans_req_t));
+
+
+  return (1);
+}