Beispiel #1
0
static void smb_tr2_find2_parse_entries(smb_file **files_p, smb_tr2_find2_entry *iter, size_t count, uint8_t *eod)
{
    smb_file *tmp = NULL;
    size_t   i;

    for (i = 0; i < count && (uint8_t *)iter < eod; i++)
    {
        // Create a smb_file and fill it
        tmp = calloc(1, sizeof(smb_file));
        if (!tmp)
            return;

        tmp->name_len = smb_from_utf16((const char *)iter->name, iter->name_len,
                                       &tmp->name);
        tmp->name[tmp->name_len] = 0;

        tmp->created    = iter->created;
        tmp->accessed   = iter->accessed;
        tmp->written    = iter->written;
        tmp->changed    = iter->changed;
        tmp->size       = iter->size;
        tmp->alloc_size = iter->alloc_size;
        tmp->attr       = iter->attr;
        tmp->is_dir     = tmp->attr & SMB_ATTR_DIR;

        tmp->next = *files_p;
        *files_p  = tmp;

        iter = (smb_tr2_find2_entry *)(((char *)iter) + iter->next_entry);
    }

    return;
}
Beispiel #2
0
static smb_file *smb_find_parse(smb_message *msg)
{
  smb_trans2_resp       *tr2;
  smb_tr2_find2_params  *params;
  smb_tr2_find2_entry   *iter;
  smb_file              *files, *tmp;
  uint8_t               *eod;
  size_t                count, i;

  assert(msg != NULL);

  // Let's parse the answer we got from server
  tr2     = (smb_trans2_resp *)msg->packet->payload;
  params  = (smb_tr2_find2_params *)tr2->payload;
  iter    = (smb_tr2_find2_entry *)(tr2->payload + sizeof(smb_tr2_find2_params));
  eod     = msg->packet->payload + msg->payload_size;
  count   = params->count;
  files   = NULL;

  for(i = 0; i < count && (uint8_t *)iter < eod; i++)
  {
    // Create a smb_file and fill it
    tmp = calloc(1, sizeof(smb_file));
    assert(tmp != NULL);

    tmp->name_len = smb_from_utf16((const char *)iter->name, iter->name_len,
                                  &tmp->name);
    tmp->name[tmp->name_len] = 0;

    tmp->created    = iter->created;
    tmp->accessed   = iter->accessed;
    tmp->written    = iter->written;
    tmp->changed    = iter->changed;
    tmp->size       = iter->size;
    tmp->alloc_size = iter->alloc_size;
    tmp->attr       = iter->attr;
    tmp->is_dir     = tmp->attr & SMB_ATTR_DIR;

    tmp->next = files;
    files     = tmp;

    iter = (smb_tr2_find2_entry *)(((char *)iter) + iter->next_entry);
  }

  return (files);
}
Beispiel #3
0
// Here we parse the NetShareEnumAll response packet payload to extract
// The share list.
static ssize_t  smb_share_parse_enum(smb_message *msg, char ***list)
{
    uint32_t          share_count, i;
    uint8_t           *data, *eod;
    uint32_t          *p_share_count;

    assert(msg != NULL && list != NULL);

    if( msg != NULL && list != NULL ) {

        // Let's skip smb parameters and DCE/RPC stuff until we are at the begginning of
        // NetShareCtrl

        p_share_count = (uint32_t *)(msg->packet->payload + 60);
        share_count = *p_share_count;
        data        = msg->packet->payload + 72 + share_count * 12;
        eod         = msg->packet->payload + msg->payload_size;

        *list       = calloc(share_count + 1, sizeof(char *));
        if (!(*list))
            return -1;

        for (i = 0; i < share_count && data < eod; i++)
        {
            uint32_t name_len, com_len;

            name_len = *((uint32_t *)data);   // Read 'Max Count', make it a multiple of 2
            data    += 3 * sizeof(uint32_t);  // Move pointer to beginning of Name.

            smb_from_utf16((const char *)data, name_len * 2, (*list) + i);

            if (name_len % 2) name_len += 1;  // Align next move
            data    += name_len * 2;          // Move the pointer to Comment 'Max count'

            com_len  = *((uint32_t *)data);
            data    += 3 * sizeof(uint32_t);  // Move pointer to beginning of Comment.
            if (com_len % 2) com_len += 1;    // Align next move
            data    += com_len * 2;           // Move the pointer to next item
        }

        return i;
    }

    return -1;
}
Beispiel #4
0
smb_file  *smb_fstat(smb_session *s, smb_tid tid, const char *path)
{
  smb_message           *msg, reply;
  smb_trans2_req        *tr2;
  smb_trans2_resp       *tr2_resp;
  smb_tr2_query         *query;
  smb_tr2_path_info     *info;
  smb_file              *file;
  size_t                path_len, msg_len;
  int                   res;

  assert(s != NULL && path != NULL && tid);

  path_len  = strlen(path) + 1;
  msg_len   = sizeof(smb_trans2_req) + sizeof(smb_tr2_query);
  msg_len  += path_len * 2 + 3; // +3 for eventual padding

  msg = smb_message_new(SMB_CMD_TRANS2, msg_len);
  smb_message_set_default_flags(msg);
  msg->packet->header.tid = tid;

  tr2 = (smb_trans2_req *)msg->packet->payload;
  tr2->wct                = 15;
  tr2->total_param_count  = path_len * 2 + sizeof(smb_tr2_query);
  tr2->max_param_count    = 2; // ?? Why not the same or 12 ?
  tr2->max_data_count     = 0xffff;
  tr2->param_count        = tr2->total_param_count;
  tr2->param_offset       = 68; // Offset of find_first_params in packet;
  tr2->data_count         = 0;
  tr2->data_offset        = 96; // Offset of pattern in packet
  tr2->setup_count        = 1;
  tr2->cmd                = SMB_TR2_QUERY_PATH;
  tr2->bct                = sizeof(smb_tr2_query) + path_len * 2 + 3;

  query = (smb_tr2_query *)tr2->payload;
  query->interest   = 0x0107;   // Query File All Info

  smb_message_advance(msg, sizeof(smb_trans2_req));
  smb_message_advance(msg, sizeof(smb_tr2_query));
  smb_message_put_utf16(msg, "", path, path_len);

  // Adds padding at the end if necessary.
  if (msg->cursor % 4)
  {
    int padding = 4 - msg->cursor % 4;
    tr2->bct += padding;
    for (int i = 0; i < padding; i++)
      smb_message_put8(msg, 0);
  }

  res = smb_session_send_msg(s, msg);
  smb_message_destroy(msg);
  if (!res)
  {
    BDSM_dbg("Unable to query pattern: %s\n", path);
    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", path);
    return (NULL);
  }

  tr2_resp  = (smb_trans2_resp *)reply.packet->payload;
  info      = (smb_tr2_path_info *)(tr2_resp->payload + 4); //+4 is padding
  file      = calloc(1, sizeof(smb_file));
  assert(file != NULL);

  file->name_len  = smb_from_utf16((const char *)info->name, info->name_len,
                                  &file->name);
  file->name[info->name_len] = 0;

  file->created     = info->created;
  file->accessed    = info->accessed;
  file->written     = info->written;
  file->changed     = info->changed;
  file->alloc_size  = info->alloc_size;
  file->size        = info->size;
  file->attr        = info->attr;
  file->is_dir      = info->is_dir;

  return (file);
}
Beispiel #5
0
smb_file  *smb_fstat(smb_session *s, smb_tid tid, const char *path)
{
    smb_message           *msg, reply;
    smb_trans2_req        tr2;
    smb_trans2_resp       *tr2_resp;
    smb_tr2_query         query;
    smb_tr2_path_info     *info;
    smb_file              *file;
    size_t                utf_path_len, msg_len;
    char                  *utf_path;
    int                   res, padding = 0;

    assert(s != NULL && path != NULL);

    utf_path_len = smb_to_utf16(path, strlen(path) + 1, &utf_path);
    if (utf_path_len == 0)
        return 0;

    msg_len   = sizeof(smb_trans2_req) + sizeof(smb_tr2_query);
    msg_len  += utf_path_len;
    if (msg_len %4)
        padding = 4 - msg_len % 4;

    msg = smb_message_new(SMB_CMD_TRANS2);
    if (!msg) {
        free(utf_path);
        return 0;
    }
    msg->packet->header.tid = tid;

    SMB_MSG_INIT_PKT(tr2);
    tr2.wct                = 15;
    tr2.total_param_count  = utf_path_len + sizeof(smb_tr2_query);
    tr2.param_count        = tr2.total_param_count;
    tr2.max_param_count    = 2; // ?? Why not the same or 12 ?
    tr2.max_data_count     = 0xffff;
    tr2.param_offset       = 68; // Offset of find_first_params in packet;
    tr2.data_count         = 0;
    tr2.data_offset        = 96; // Offset of pattern in packet
    tr2.setup_count        = 1;
    tr2.cmd                = SMB_TR2_QUERY_PATH;
    tr2.bct                = sizeof(smb_tr2_query) + utf_path_len + padding;
    SMB_MSG_PUT_PKT(msg, tr2);

    SMB_MSG_INIT_PKT(query);
    query.interest   = SMB_FIND2_QUERY_FILE_ALL_INFO;
    SMB_MSG_PUT_PKT(msg, query);

    smb_message_append(msg, utf_path, utf_path_len);
    free(utf_path);

    // Adds padding at the end if necessary.
    while (padding--)
        smb_message_put8(msg, 0);

    res = smb_session_send_msg(s, msg);
    smb_message_destroy(msg);
    if (!res)
    {
        BDSM_dbg("Unable to query pattern: %s\n", path);
        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", path);
        return NULL;
    }

    tr2_resp  = (smb_trans2_resp *)reply.packet->payload;
    info      = (smb_tr2_path_info *)(tr2_resp->payload + 4); //+4 is padding
    file      = calloc(1, sizeof(smb_file));
    if (!file)
        return NULL;

    file->name_len  = smb_from_utf16((const char *)info->name, info->name_len,
                                     &file->name);
    file->name[info->name_len / 2] = 0;

    file->created     = info->created;
    file->accessed    = info->accessed;
    file->written     = info->written;
    file->changed     = info->changed;
    file->alloc_size  = info->alloc_size;
    file->size        = info->size;
    file->attr        = info->attr;
    file->is_dir      = info->is_dir;

    return file;
}