Example #1
0
static int init_smb_response(struct smb_response* sr,unsigned char* in_response_to,size_t size) {
  if (size<200) size=200;
  sr->buf=malloc(sr->allocated=size);
  if (!sr->buf) return -1;

  sr->used=netbiosheadersize+smbheadersize;

  uint32_pack_big(sr->buf,32);	// size field in NMB header
  byte_copy(sr->buf+netbiosheadersize,smbheadersize-8,
	    "\xffSMB"	// magic
	    "x"		// smb command, filled in later; ofs 4
	    "\x00\x00\x00\x00"	// STATUS_SUCCESS
	    "\x80"	// Flags: response+case sensitive
	    "\x41\xc0"	// Flags2: unicode+long names allowed
	    "\x00\x00"	// Process ID High: 0
	    "\x00\x00\x00\x00\x00\x00\x00\x00"	// Signature
	    "\x00\x00"	// Reserved
	   );		// TID, PID, UID, MID; ofs 24

  sr->buf[netbiosheadersize+4]=in_response_to[4];
  uint16_pack(sr->buf+netbiosheadersize+24,uint16_read((char*)in_response_to+24));
  uint16_pack(sr->buf+netbiosheadersize+26,uint16_read((char*)in_response_to+26));
  uint16_pack(sr->buf+netbiosheadersize+28,0);
  uint16_pack(sr->buf+netbiosheadersize+30,uint16_read((char*)in_response_to+30));

  sr->andxtypeofs=netbiosheadersize+4;

  return 0;
}
Example #2
0
static int smb_handle_echo(unsigned char* c,size_t len,struct smb_response* sr) {
  uint16 nmemb,membsize;
  char* buf;
  size_t i;
  if (len<2*1 || c[0] != 1) return -1;	/* word count for this message is always 1 */
  nmemb=uint16_read((char*)c+1);
  membsize=uint16_read((char*)c+3);
  if (nmemb*membsize>1024) return -1;
  buf=alloca(nmemb*membsize+3);
  buf[0]=0;
  uint16_pack(buf+1,nmemb*membsize);
  for (i=0; i<nmemb; ++i)
    byte_copy(buf+3+i*membsize,membsize,c+5);
  return add_smb_response(sr,buf,nmemb*membsize+3,0x2b);
}
Example #3
0
static int validate_smb_packet(unsigned char* pkt,unsigned long len) {
  /* we actually received len bytes from the wire, so pkt+len does not
   * overflow; we got len bytes, because the netbios header said there
   * were that many bytes in the packet. */
  unsigned char* x;
  /* demand that we have at least a full smbheader and wordcount */
  if (len>=smbheadersize+1 &&
      byte_equal(pkt,4,"\xffSMB")) {	/* signature needs to be there */
    x=(unsigned char*)pkt+smbheadersize;
    if (x[0] > 100)
      return -1;
    /* see that x + sizeof(word_count) + word_count*2 +
     * sizeof(byte_count) is inside the packet */
    if (!range_arrayinbuf(pkt,len,x+3,*x,2))
      return -1;
    /* now we know the word count is ok, but is the byte count? */
    {
      size_t bytecountofs=1+*x*2;
      size_t bytecount;
      bytecount=uint16_read((const char*)x+bytecountofs);
      if (bytecount>len || x+bytecountofs+2+bytecount>pkt+len) return -1;
    }
    if (!hasandx(pkt[4])) return 0;
    for (;;) {
      size_t bytecount;
      /* see that x + sizeof(word_count) + word_count*2 +
      * sizeof(byte_count) is inside the packet */
      if (!range_arrayinbuf(pkt,len,x+3,*x,2))
	return -1;
      /* we know that the byte count is within the packet */
      /* read it and check whether it's ok, too */
      bytecount=uint16_read((const char*)x+1+*x*2);
      if (!range_arrayinbuf(pkt,len,x+3+bytecount,*x,2))
	return -1;
      if (x[1]==0xff) return 0;
      {
	uint16_t next=uint16_read((char*)x+3);
	if (pkt+next < x+1+x[0]*2+2+bytecount) return -1;	/* can't point backwards */
	x=pkt+next;
      }
      if (!range_bufinbuf(pkt,len,(char*)x,5))
	return -1;
    }
  } else
    return -1;
  return 0;
}
Example #4
0
static int smb_handle_negotiate_request(unsigned char* c,size_t len,struct smb_response* sr) {
  size_t i,j,k;
  int ack;
  const char nr[2*17+100*2]=
    "\x11"	// word count 17
    "xx"	// dialect index; ofs 1
    "\x02"	// security mode, for NT: plaintext passwords XOR unicode
#if 0
    "\x02\x00"	// Max Mpx Count 2
    "\x01\x00"	// Max VCs 1
#else
    "\x10\x00"	// Max Mpx Count 16
    "\x10\x00"	// Max VCs 16
#endif
    "\x04\x41\x00\x00"	// Max Buffer Size (16644, like XP)
    "\x00\x00\x01\x00"	// Max Raw Buffer (65536, like XP)
    "\x01\x02\x03\x04"	// Session Key
    "\x5e\x40\x00\x00"	// Capabilities, the bare minimum
    "xxxxxxxx"	// system time; ofs 24
    "xx"	// server time zone; ofs 32
    "\x00"	// key len
    "xx"	// byte count; ofs 35
    ;		// workgroup name; ofs 37
  char* x;

  if (len<3) return -1;
  j=uint16_read((char*)c+1);
  if (len<3+j) return -1;
  ack=-1;
  for (k=0,i=3; i<3+j; ++k) {
    if (c[i]!=2) return -1;
    if (str_equal((char*)c+i+1,"NT LM 0.12")) { ack=k; break; }
    i+=2+str_len((char*)c+i+1);
  }
  if (ack==-1) return -1;	// wrong dialect

  if (!(x=add_smb_response2(sr,nr,38+wglen16,0x72))) return -1;
  uint16_pack(x+1,ack);

  {
    struct timeval t;
    unsigned long long ntdate;
    gettimeofday(&t,&tz);
    ntdate=10000000ll * ( t.tv_sec + 11644473600ll ) + t.tv_usec * 10ll;
    uint32_pack(x+24,ntdate&0xffffffff);
    uint32_pack(x+24+4,ntdate>>32);
    uint16_pack(x+32,tz.tz_minuteswest);
  }

  uint16_pack(x+35,wglen16);
  byte_copy(x+37,wglen16,workgroup_utf16);

  return 0;
}
Example #5
0
/* returns number of converted chars in dest, including \0, or 0 on error */
static size_t utf16tolatin1(char* dest,size_t dsize,uint16_t* src,size_t ssize) {
  size_t i;
  size_t max=dsize;
  if (ssize/2<max) max=ssize/2;
  for (i=0; i<max; ++i) {
    uint16_t x=uint16_read((char*)&src[i]);
    if (x>0xff) return 0;
    dest[i]=x;
  }
  if (i==dsize) return 0;
  dest[i]=0;
  return i+1;
}
Example #6
0
uint64
elf_get_value(void* elf, void* ptr, unsigned off32, unsigned size32, unsigned off64, unsigned size64) {
  uint8* base = elf;
  uint8* p = ptr;
  unsigned off, size;
  uint64 ret = 0;
  if(ELF_32(base)) {
    off = off32;
    size = size32;
  } else {
    off = off64;
    size = size64;
  }
  switch(size) {
    case 8: ret = uint64_read((const char*)&p[off]); break;
    case 4: ret = uint32_read((const char*)&p[off]); break;
    case 2: ret = uint16_read((const char*)&p[off]); break;
    case 1: ret = p[off]; break;
  }
  return ret;
}
Example #7
0
static int smb_handle_OpenAndX(struct http_data* h,unsigned char* c,size_t len,uint32_t pid,struct smb_response* sr) {
  static const char nr[34]=
    "\x0f"	// word count 15
    "\xff"	// AndXCommand
    "\x00"	// Reserved
    "w1"	// AndXOffset; ofs 3
    "w2"	// FID; ofs 5
    "\x00\x00"	// file attributes; normal file
    "u1__"	// ctime; ofs 9
    "u2__"	// file size; ofs 13
    "\x00\x00"	// granted access: read, compatibility mode, caching permitted
    "\x00\x00"	// file type: disk file or directory
    "\x00\x00"	// ipc state
    "\x01\x00"  // action: file existed and was opened
    "\x00\x00\x00\x00"	// server FID (?!?)
    "\x00\x00"	// reserved
    "\x00\x00"	// byte count 0
    ;
  if (len<2*15 || c[0]!=15) return -1;
  /* see if it is an open for reading */
  if ((c[7]&7) || ((c[17]&3)!=1)) {
    /* we only support read access */
//    printf("non-read-access requested: %x %x!\n",c[7],c[17]);
    set_smb_error(sr,ERROR_ACCESS_DENIED,0x2d);
    return 0;
  }
  /* now look at file name */
  {
    size_t fnlen=uint16_read((char*)c+31);
    uint16_t* remotefilename=(uint16_t*)(c+34);
    struct stat ss;
    struct handle* hdl;
    int fd;
    char* x;
    if (fnlen%2) --fnlen;
    if (fnlen>2046 || ((uintptr_t)remotefilename%2)) return -1;
    hdl=alloc_handle(&h->h);
    if (!hdl) {
//      printf("could not open file handle!");
      set_smb_error(sr,STATUS_TOO_MANY_OPENED_FILES,0x2d);
      return 0;
    }

    fd=smb_open(h,remotefilename,fnlen,&ss,WANT_OPEN);
    if (fd==-1) {
      set_smb_error(sr,ERROR_OBJECT_NAME_NOT_FOUND,0x2d);
      close_handle(hdl);
      return 0;
    }
    hdl->fd=fd;
    hdl->pid=pid;
    hdl->size=ss.st_size;
    hdl->cur=0;
    hdl->filename=malloc(fnlen+2);
    if (hdl->filename) {
      memcpy(hdl->filename+1,remotefilename,fnlen);
      hdl->filename[0]=fnlen;
    }

    {
      size_t oldlen=sr->used;
      if (!(x=add_smb_response2(sr,nr,15*2+3,0x2d))) return -1;
      uint16_pack(x+OFS16(nr,"w1"),oldlen+15*2+3);
    }

    uint16_pack(x+OFS16(nr,"w2"),hdl->handle);
    uint32_pack(x+OFS16(nr,"u1"),ss.st_mtime);
    uint32_pack(x+OFS16(nr,"u2"),ss.st_size);
  }
  return 0;
}