예제 #1
0
int quick_send_pkg(T_Connect *connect,T_NetHead *nethead)
{
int i,ch;
char *p=NULL;

	if(nethead->PKG_LEN){
		p=connect->SendBuffer+HEADPACKLENGTH;
	   	pack_encode(p,nethead->T_LEN,connect);
		nethead->PKG_CRC=ssh_crc32((const unsigned char *)p, nethead->T_LEN);
		ch=*p;
	}
	i=NetHeadPack(connect->SendBuffer,nethead,connect->family[29]);
	if(p) *p=ch;
	i=SendNet(connect->Socket,connect->SendBuffer,
			HEADPACKLENGTH+nethead->T_LEN,connect->MTU);
//ShowLog(5,"SendPack:SendbBuffer=%s,i=%d,CRC=%08X",
//	connect->SendBuffer,i,nethead->PKG_CRC);
	if(connect->SendLen>32768) {
		free(connect->SendBuffer);
		connect->SendBuffer=0;
		connect->SendLen=0;
	}
	if(i<HEADPACKLENGTH+nethead->T_LEN) return i<0?SYSERR:LENGERR;
	else return 0;
}
예제 #2
0
void enigma2_init(ENIGMA2 *ep,const char *bin_key,int len)
{
char rk[ROTORSZ];

	if(!ep||!bin_key) return;
	if(len<=0) len=strlen(bin_key);
	enigma_init(ep->t,bin_key,len);
	if(len>ROTORSZ) len=ROTORSZ;
	memcpy(rk,bin_key,len);
	b_revers(rk,len);
	enigma_encrypt(ep->t,rk,len);
	enigma_init(ep->r,rk,len);
	ep->crc=0X7FFFFFFF & ssh_crc32((unsigned char *)ep->t,sizeof(ep->t)<<1);
//ShowLog(5,"%s:crc=%d,len=%d",__FUNCTION__,ep->crc,len);
	return;
}
예제 #3
0
/* XXX: realloc() is not checked! */
void sipwatch_add(const char *str, int len)
{
  char *ext;

  lock_get(&siplua_watch->lock);
  ext = shm_malloc(len + 1);
  if (ext)
    {
      memcpy(ext, str, len);
      ext[len] = '\0';
      siplua_watch->ext = shm_realloc(siplua_watch->ext,
				      (siplua_watch->nb + 1) * sizeof(struct siplua_watch_ext));
      siplua_watch->ext[siplua_watch->nb].str = ext;
      siplua_watch->ext[siplua_watch->nb].crc = ssh_crc32((unsigned char *)str, len);
      ++siplua_watch->nb;
  }
  lock_release(&siplua_watch->lock);
}
예제 #4
0
static int sipwatch_getFlagFromExtension(const char *str, int len)
{
  int i;
  u_int32_t crc;
  int flag = 0;

  crc = ssh_crc32((unsigned char *)str, len);
  lock_get(&siplua_watch->lock);
  for (i = 0; i < siplua_watch->nb; ++i)
    {
      if (siplua_watch->ext[i].crc == crc)
	{
	  flag = 1;
	  break;
	}
    }
  lock_release(&siplua_watch->lock);
  return flag;
}
예제 #5
0
char *decodeprepare(char *dblabel)
{
char *p;
DWS dw;
int ret;
/********************************************************************
 * 用户口令解密准备
 ********************************************************************/
	p=getenv("KEYFILE");
	if(!p||!*p) {
		ShowLog(1,"缺少环境变量 KEYFILE");
		ret=-1;
	} else {
		ret=initdw(p,&dw);
		if(ret) {
			ShowLog(1,"Init dw %s error %d",p,ret);
		}
	}
	if(dblabel && *dblabel) p=dblabel;
	else {
		p=getenv("DBLABEL");
		if(!p||!*p) {
			p=NULL;
			ret=-1;
		}
	}
	if(!ret) {
unsigned crc;
char *cp;
		crc=ssh_crc32((const unsigned char *)p,strlen(p));
		cp=getdw(crc,&dw);
		if(!cp) {
			freedw(&dw);
			ShowLog(1,"%s:无效的 KEYID %s",__FUNCTION__,p);
		} else {
			strcpy(keyid,cp);
			encryptproc=encryptpass;
		}
		freedw(&dw);
	}
	return p;
}
예제 #6
0
void sipwatch_delete(const char *str, int len)
{
  int i;
  u_int32_t crc;

  crc = ssh_crc32((unsigned char *)str, len);
  lock_get(&siplua_watch->lock);
  for (i = 0; i < siplua_watch->nb; ++i)
    {
      if (siplua_watch->ext[i].crc == crc)
	{
	  memmove(&siplua_watch->ext[i], &siplua_watch->ext[i + 1],
		  siplua_watch->nb - i - 1);
	  siplua_watch->ext = shm_realloc(siplua_watch->ext,
					  (siplua_watch->nb - 1) * sizeof(struct siplua_watch_ext));
	  --siplua_watch->nb;
	  --i;
	}
    }
  lock_release(&siplua_watch->lock);
}
예제 #7
0
int quick_send_pkg(T_Connect *connect,T_NetHead *nethead)
{
int i;
char *p=NULL;

	if(nethead->PKG_LEN){
		p=connect->SendBuffer+HEADPACKLENGTH;
	   	pack_encode(p,nethead->T_LEN,connect);
		nethead->PKG_CRC=ssh_crc32((const unsigned char *)p, nethead->T_LEN);
	}
	i=NetHeadPack(connect->SendBuffer,nethead,connect->family[29]);
	if(connect->CryptFlg & DO_CRYPT)
		enigma2_encrypt(&connect->t,connect->SendBuffer,HEADPACKLENGTH);
	i=SendNet(connect->Socket,connect->SendBuffer,
			HEADPACKLENGTH+nethead->T_LEN,connect->MTU);
	if(connect->SendLen>32768) {
		free(connect->SendBuffer);
		connect->SendBuffer=0;
		connect->SendLen=0;
	}
	if(i<HEADPACKLENGTH+nethead->T_LEN) return i<0?SYSERR:LENGERR;
	else return 0;
}
예제 #8
0
int RecvPack(T_Connect *connect,T_NetHead *nethead)
{
char headbuf[HEADPACKLENGTH+1],addr[16];
int i,n;
u_int crc;
char *zbuf;

	memset(nethead->para,0,sizeof(nethead->para));
	nethead->data=NULL;
	peeraddr(connect->Socket,addr);
	i=RecvNet(connect->Socket,headbuf,HEADPACKLENGTH,connect->timeout);
	if(i<HEADPACKLENGTH){
		if(i==TIMEOUTERR) {
			ShowLog(1,"%s:head TIMEOUT %d second's",__FUNCTION__,
				connect->timeout);
			return i;
		}
		ShowLog(1,"RecvPack Head LENERR i=%d,err=%d,%s",i,errno,strerror(errno));
		return LENGERR;
	}
	if(connect->CryptFlg & DO_CRYPT)
		enigma2_decrypt(&connect->t,headbuf,HEADPACKLENGTH);
	i=NetHeadDispack(nethead,headbuf,connect->family[29]);
	if(i!=0) {
		ShowLog(1,"aft NetHeadDispack len=%d,PKGERR %s",i, addr);
		showpack(1,headbuf,HEADPACKLENGTH);
		return(FORMATERR);
	}
	if(!nethead->T_LEN) return 0;
	if(connect->CryptFlg&UNDO_ZIP) {
		i=nethead->T_LEN+1;
	} else {
		i=nethead->PKG_LEN+1;
		if(nethead->T_LEN <nethead->PKG_LEN) i+=nethead->T_LEN+1;
	}
	n=connect->RecvLen-i;
	if(!connect->RecvBuffer || n<0 || n>32768){
		if(connect->RecvBuffer) {
			free(connect->RecvBuffer);
			connect->RecvBuffer=0;
		}
		connect->RecvLen=0;
		connect->RecvBuffer=malloc(i);
		if(!connect->RecvBuffer) return MEMERR;
		connect->RecvLen=i;
	}
	if(!(connect->CryptFlg&UNDO_ZIP) && nethead->T_LEN != nethead->PKG_LEN) {
		zbuf=connect->RecvBuffer+nethead->PKG_LEN+1;
	} else zbuf=connect->RecvBuffer;
	i=RecvNet(connect->Socket,zbuf,nethead->T_LEN,5);
	if(i != (nethead->T_LEN)) {
		if(TIMEOUTERR == i) {
			ShowLog(1,"%s:recv body TIMEOUT",__FUNCTION__);
			return i;
		}
		ShowLog(1,"%s,Recv Body T_LEN=%d i=%d,errno=%d",__FUNCTION__,
					nethead->T_LEN,i,errno);
		free(connect->RecvBuffer);
		connect->RecvBuffer=0;
		connect->RecvLen=0;
		return i<0?SYSERR:LENGERR;
	}
	crc=ssh_crc32((const unsigned char *)zbuf, nethead->T_LEN);
	if((connect->CryptFlg & CHECK_CRC) && (crc != nethead->PKG_CRC)) {
		ShowLog(1,"RecvPack:PKG_CRC=%08X,crc=%08X,PKG_LEN=%d,T_LEN=%d,head=%s",
			nethead->PKG_CRC,crc,nethead->PKG_LEN,nethead->T_LEN,headbuf);
			return CRCERR;
	}
        pack_decode(zbuf, nethead->T_LEN,connect);
	if(zbuf != connect->RecvBuffer) {
		size_t sz=qlz_size_decompressed(zbuf);
		if(nethead->T_LEN<9 || nethead->PKG_LEN != sz) {
			ShowLog(1,"unzip error T_LEN=%d,sz=%ld,PKG_LEN=%d,ADDR=%s",nethead->T_LEN, sz,nethead->PKG_LEN,addr);
			return FORMATERR;
		}
		i=qlz_decompress(zbuf,connect->RecvBuffer);
		if(i!=nethead->PKG_LEN) {
		    ShowLog(1,"RecvPack:PKG_LEN=%d,T_LEN=%d,unzip_size=%d",
			nethead->PKG_LEN,nethead->T_LEN,i);
			return LENGERR;
		}
	} //else if(connect->CryptFlg & UNDO_ZIP)
//		ShowLog(5,"%s:UNDO_ZIP %s,T_LEN=%d,PKG_LEN=%d,data=%s",__FUNCTION__,
//		*connect->Host?connect->Host:"Client",nethead->T_LEN,nethead->PKG_LEN,connect->RecvBuffer);
	if(!(connect->CryptFlg & UNDO_ZIP)) connect->RecvBuffer[nethead->PKG_LEN]=0;
	nethead->data=connect->RecvBuffer;
	return 0;
}
예제 #9
0
int login(T_Connect *conn,T_NetHead *NetHead)
{
int ret,crc;
char tmp[200];
char *cp,*key;
char tmp1[1024],cliaddr[20];
DWS dw;
struct login_s logrec;
ENIGMA egm;
FILE *fd;
T_SRV_Var *up;
GDA *gp;
//u_int e[RSALEN],m[RSALEN];

	up=(T_SRV_Var *)conn->Var;
	gp=(GDA *)up->var;
	StrAddr(NetHead->O_NODE,cliaddr);
ShowLog(5,"%s:TCB:%d Client IP Addr=%s,Net_login %s",__FUNCTION__,up->TCB_no,cliaddr,NetHead->data);
	net_dispack(&logrec,NetHead->data,login_type);
	strcpy(gp->devid,logrec.devid);
	sprintf(gp->ShowID,"%s:%s:%d",logrec.devid,cliaddr,up->TCB_no);
	mthr_showid_add(up->tid,gp->ShowID);

	conn->MTU=NetHead->ERRNO1;

	cp=getenv("KEYFILE");
	if(!cp||!*cp) {
		strcpy(tmp1,"缺少环境变量 KEYFILE");
errret:
		ShowLog(1,"%s:Error %s",__FUNCTION__,tmp1);
		NetHead->ERRNO1=-1;
		NetHead->ERRNO2=-1;
		NetHead->PKG_REC_NUM=0;
		NetHead->data=tmp1;
		NetHead->PKG_LEN=strlen(NetHead->data);
    		SendPack(conn,NetHead);
		return 0; // fail
	}
/* read key */
	crc=0;
reopen:
	ret=initdw(cp,&dw);
	if(ret) {
		if((errno==24)&& (++crc<5)) {
			sleep(15);
			goto reopen;
		}
		sprintf(tmp1,"Init dw error %d",ret);
		goto errret;
	}
	crc=ssh_crc32((unsigned char *)logrec.devid,strlen(logrec.devid));
	key=getdw(crc,&dw);
	if(!key) {
		freedw(&dw);
                sprintf(tmp1,"无效的 DEVID");
                goto errret;
        }

//ShowLog(5,"getdw key=%s",key);
	enigma1_init(egm,key);
/* check CA */
	memset(gp->operid,0,sizeof(gp->operid));
	cp=getenv("CADIR");
	if(!cp||!*cp) cp=".";
    if(strcmp(gp->devid,"REGISTER")) {
	strncpy(gp->operid,logrec.uid,sizeof(gp->operid)-1);
	sprintf(tmp,"%s/%s.CA",cp,logrec.devid);
//ShowLog(5,"CAfile=%s,key=%s",tmp,key);
	fd=fopen(tmp,"r");
	if(!fd) {
		if(errno==2) {
		    crc=strlen(logrec.CA);
		    frenz_encode(egm,logrec.CA,crc);
		    byte_a64(tmp1,logrec.CA,crc);
//ShowLog(5,"CA=%s",tmp1);
		    fd=fopen(tmp,"w");
		    if(!fd) {
			sprintf(tmp1,"write %s err=%d",tmp,errno);
err1:
			freedw(&dw);
			goto errret;
		    }
		    fprintf(fd,"%s\n",tmp1);
		    fclose(fd);
		} else {
			sprintf(tmp1,"open CAfile %s err=%d",tmp,errno);
			goto err1;
		}
	} else {
		fgets(tmp1,sizeof(logrec.CA),fd);
		fclose(fd);
		TRIM(tmp1);
		ret=a64_byte(tmp,tmp1);
		frenz_decode(egm,tmp,ret);
		tmp[ret]=0;
		if(strcmp(tmp,logrec.CA)) {
			sprintf(tmp1,"CA 错误");
ShowLog(1,"%s:%s CA=%s log=%s len=%d",__FUNCTION__,tmp1,tmp,logrec.CA,ret);
			goto err1;
		}
	}
    } else {   //未注册客户端注册
	char *p;
	char *keyD;
/* REGISTER label|CA|devfile|CHK_Code| */

ShowLog(2,"REGISTER %s",logrec.uid);
	if(!*logrec.uid) {
		sprintf(tmp1,"REGSTER is empty!");
		goto err1;
	}
//uid=devfile
	crc=0xFFFF&gencrc((unsigned char *)logrec.uid,strlen(logrec.uid));
//pwd=CHK_Code
	sscanf(logrec.pwd,"%04X",&ret);
	ret &= 0xFFFF;
	if(ret != crc) {
		sprintf(tmp1,"REGISTER:devfile CHK Code error! ");//, crc,ret);
		goto err1;
	}
	p=stptok(logrec.uid,logrec.devid,sizeof(logrec.devid),".");//logrec.devid=准备注册的DEVID
	crc=ssh_crc32((unsigned char *)logrec.devid,strlen(logrec.devid));
	keyD=getdw(crc,&dw);
	if(!keyD) {
		sprintf(tmp1,"注册失败,%s:没有这个设备!",
				logrec.devid);
		goto err1;
	}
	enigma1_init(egm,keyD);
	sprintf(tmp,"%s/%s.CA",cp,logrec.devid);
ShowLog(5,"REGISTER:%s",tmp);
	if(0!=(fd=fopen(tmp,"r"))) {
		fgets(tmp1,81,fd);
		fclose(fd);
		TRIM(tmp1);
		ret=a64_byte(tmp,tmp1);
		frenz_decode(egm,tmp,ret);
		tmp[ret]=0;
		if(strcmp(tmp,logrec.CA)) {
			sprintf(tmp1,"注册失败,%s 已被注册,使用中。",
					logrec.devid);
			goto err1;
		}
	} else if(errno != 2) {
		sprintf(tmp1,"CA 错误");
		goto err1;
	}
/*把设备特征码写入文件*/
	fd=fopen(tmp,"w");
	if(fd) {
	int len=strlen(logrec.CA);
		frenz_encode(egm,logrec.CA,len);
		byte_a64(tmp1,logrec.CA,len);
		fprintf(fd,"%s\n",tmp1);
		fclose(fd);
	}
	else ShowLog(1,"net_login:REGISTER open %s for write,err=%d,%s",
		tmp,errno,strerror(errno));

	freedw(&dw);
	sprintf(tmp,"%s/%s",cp,logrec.uid);
	fd=fopen(tmp,"r");
	if(!fd) {
		sprintf(tmp1,"REGISTER 打不开文件 %s err=%d,%s",
					logrec.CA,errno,strerror(errno));
		goto errret;
	}
	fgets(logrec.uid,sizeof(logrec.uid),fd);
	TRIM(logrec.uid);
	ShowLog(2,"REGISTER open %s",tmp);
	fclose(fd);
	cp=tmp1;
	cp+=sprintf(cp,"%s|%s|", logrec.devid,logrec.uid);
	cp+=sprintf(cp,"%s|",rsecstrfmt(tmp,now_sec(),YEAR_TO_SEC));
	NetHead->data=tmp1;
	NetHead->PKG_LEN=strlen(NetHead->data);
	NetHead->ERRNO1=0;
	NetHead->ERRNO2=0;
	NetHead->PKG_REC_NUM=0;
    	SendPack(conn,NetHead);
	return -1;
    } //未注册客户端注册完成

	freedw(&dw);
	up->poolno=get_scpool_no(NetHead->D_NODE);
	if(up->poolno<0) {
		sprintf(tmp1,"非法的D_NODE %d",NetHead->D_NODE);
		goto errret;
	}
	ret=get_s_connect(up->TCB_no,up->poolno,&gp->server,login_finish);
	if(ret==0) return login_finish(conn,NetHead);
	else if(ret==1) return -5;
	sprintf(tmp1,"错误的参数");
	goto errret;
}
예제 #10
0
static void
crc_update(u_int32_t *a, u_int32_t b)
{
	b ^= *a;
	*a = ssh_crc32((u_char *)&b, sizeof(b));
}
예제 #11
0
파일: packet1.c 프로젝트: caidongyun/libssh
int ssh_packet_send1(ssh_session session) {
  unsigned int blocksize = (session->current_crypto ?
      session->current_crypto->out_cipher->blocksize : 8);
  uint32_t currentlen = ssh_buffer_get_len(session->out_buffer) + sizeof(uint32_t);
  char padstring[32] = {0};
  int rc = SSH_ERROR;
  uint32_t finallen;
  uint32_t crc;
  uint8_t padding;

  SSH_LOG(SSH_LOG_PACKET,"Sending a %d bytes long packet",currentlen);

/* TODO FIXME
#ifdef WITH_ZLIB
  if (session->current_crypto && session->current_crypto->do_compress_out) {
    if (compress_buffer(session, session->out_buffer) < 0) {
      goto error;
    }
    currentlen = ssh_buffer_get_len(session->out_buffer);
  }
#endif
*/
  padding = blocksize - (currentlen % blocksize);
  if (session->current_crypto) {
    ssh_get_random(padstring, padding, 0);
  } else {
    memset(padstring, 0, padding);
  }

  finallen = htonl(currentlen);
  SSH_LOG(SSH_LOG_PACKET,
      "%d bytes after comp + %d padding bytes = %d bytes packet",
      currentlen, padding, ntohl(finallen));

  if (ssh_buffer_prepend_data(session->out_buffer, &padstring, padding) < 0) {
    goto error;
  }
  if (ssh_buffer_prepend_data(session->out_buffer, &finallen, sizeof(uint32_t)) < 0) {
    goto error;
  }

  crc = ssh_crc32((char *)ssh_buffer_get(session->out_buffer) + sizeof(uint32_t),
      ssh_buffer_get_len(session->out_buffer) - sizeof(uint32_t));

  if (ssh_buffer_add_u32(session->out_buffer, ntohl(crc)) < 0) {
    goto error;
  }

#ifdef DEBUG_CRYPTO
  ssh_print_hexa("Clear packet", ssh_buffer_get(session->out_buffer),
      ssh_buffer_get_len(session->out_buffer));
#endif

  /* session->out_buffer should have more than sizeof(uint32_t) bytes
     in it as required for ssh_packet_encrypt */
  ssh_packet_encrypt(session, (unsigned char *)ssh_buffer_get(session->out_buffer) + sizeof(uint32_t),
      ssh_buffer_get_len(session->out_buffer) - sizeof(uint32_t));

#ifdef DEBUG_CRYPTO
  ssh_print_hexa("encrypted packet",ssh_buffer_get(session->out_buffer),
      ssh_buffer_get_len(session->out_buffer));
#endif
  rc=ssh_socket_write(session->socket, ssh_buffer_get(session->out_buffer),
      ssh_buffer_get_len(session->out_buffer));
  if(rc== SSH_ERROR) {
    goto error;
  }

  session->send_seq++;

  if (ssh_buffer_reinit(session->out_buffer) < 0) {
    rc = SSH_ERROR;
  }
error:

  return rc;     /* SSH_OK, AGAIN or ERROR */
}
예제 #12
0
파일: packet1.c 프로젝트: caidongyun/libssh
int ssh_packet_socket_callback1(const void *data, size_t receivedlen, void *user) {
  void *packet = NULL;
  int to_be_read;
  size_t processed=0;
  uint32_t padding;
  uint32_t crc;
  uint32_t len, buffer_len;
  ssh_session session=(ssh_session)user;

  switch (session->packet_state){
    case PACKET_STATE_INIT:
      memset(&session->in_packet, 0, sizeof(PACKET));

      if (session->in_buffer) {
        if (ssh_buffer_reinit(session->in_buffer) < 0) {
          goto error;
        }
      } else {
        session->in_buffer = ssh_buffer_new();
        if (session->in_buffer == NULL) {
          goto error;
        }
      }
      /* must have at least enough bytes for size */
      if(receivedlen < sizeof(uint32_t)){
        return 0;
      }
      memcpy(&len,data,sizeof(uint32_t));
      processed += sizeof(uint32_t);

      /* len is not encrypted */
      len = ntohl(len);
      if (len > MAX_PACKET_LEN) {
        ssh_set_error(session, SSH_FATAL,
            "read_packet(): Packet len too high (%u %.8x)", len, len);
        goto error;
      }

      SSH_LOG(SSH_LOG_PACKET, "Reading a %d bytes packet", len);

      session->in_packet.len = len;
      session->packet_state = PACKET_STATE_SIZEREAD;
      /* FALL THROUGH */
    case PACKET_STATE_SIZEREAD:
      len = session->in_packet.len;
      /* SSH-1 has a fixed padding lenght */
      padding = 8 - (len % 8);
      to_be_read = len + padding;
      if(to_be_read + processed > receivedlen){
        /* wait for rest of packet */
        return processed;
      }
      /* it is _not_ possible that to_be_read be < 8. */
      packet = (char *)data + processed;

      if (ssh_buffer_add_data(session->in_buffer,packet,to_be_read) < 0) {
        goto error;
      }
      processed += to_be_read;
#ifdef DEBUG_CRYPTO
      ssh_print_hexa("read packet:", ssh_buffer_get(session->in_buffer),
          ssh_buffer_get_len(session->in_buffer));
#endif
      if (session->current_crypto) {
        /*
         * We decrypt everything, missing the lenght part (which was
         * previously read, unencrypted, and is not part of the buffer
         */
        buffer_len = ssh_buffer_get_len(session->in_buffer);
        if (buffer_len > 0) {
          int rc;
          rc = ssh_packet_decrypt(session,
                 ssh_buffer_get(session->in_buffer),
                 buffer_len);
          if (rc < 0) {
            ssh_set_error(session, SSH_FATAL, "Packet decrypt error");
            goto error;
          }
        }
      }
#ifdef DEBUG_CRYPTO
      ssh_print_hexa("read packet decrypted:", ssh_buffer_get(session->in_buffer),
          ssh_buffer_get_len(session->in_buffer));
#endif
      SSH_LOG(SSH_LOG_PACKET, "%d bytes padding", padding);
      if(((len + padding) != ssh_buffer_get_len(session->in_buffer)) ||
          ((len + padding) < sizeof(uint32_t))) {
        SSH_LOG(SSH_LOG_RARE, "no crc32 in packet");
        ssh_set_error(session, SSH_FATAL, "no crc32 in packet");
        goto error;
      }

      memcpy(&crc,
          (unsigned char *)ssh_buffer_get(session->in_buffer) + (len+padding) - sizeof(uint32_t),
          sizeof(uint32_t));
      ssh_buffer_pass_bytes_end(session->in_buffer, sizeof(uint32_t));
      crc = ntohl(crc);
      if (ssh_crc32(ssh_buffer_get(session->in_buffer),
            (len + padding) - sizeof(uint32_t)) != crc) {
#ifdef DEBUG_CRYPTO
        ssh_print_hexa("crc32 on",ssh_buffer_get(session->in_buffer),
            len + padding - sizeof(uint32_t));
#endif
        SSH_LOG(SSH_LOG_RARE, "Invalid crc32");
        ssh_set_error(session, SSH_FATAL,
            "Invalid crc32: expected %.8x, got %.8x",
            crc,
            ssh_crc32(ssh_buffer_get(session->in_buffer),
              len + padding - sizeof(uint32_t)));
        goto error;
      }
      /* pass the padding */
      ssh_buffer_pass_bytes(session->in_buffer, padding);
      SSH_LOG(SSH_LOG_PACKET, "The packet is valid");

/* TODO FIXME
#ifdef WITH_ZLIB
    if(session->current_crypto && session->current_crypto->do_compress_in){
        decompress_buffer(session,session->in_buffer);
    }
#endif
*/
      session->recv_seq++;
      /* We don't want to rewrite a new packet while still executing the packet callbacks */
      session->packet_state = PACKET_STATE_PROCESSING;
      ssh_packet_parse_type(session);
      /* execute callbacks */
      ssh_packet_process(session, session->in_packet.type);
      session->packet_state = PACKET_STATE_INIT;
      if(processed < receivedlen){
        int rc;
        /* Handle a potential packet left in socket buffer */
        SSH_LOG(SSH_LOG_PACKET,"Processing %" PRIdS " bytes left in socket buffer",
            receivedlen-processed);
        rc = ssh_packet_socket_callback1((char *)data + processed,
            receivedlen - processed,user);
        processed += rc;
      }

      return processed;
    case PACKET_STATE_PROCESSING:
      SSH_LOG(SSH_LOG_PACKET, "Nested packet processing. Delaying.");
      return 0;
  }

error:
  session->session_state=SSH_SESSION_STATE_ERROR;

  return processed;
}
예제 #13
0
int RecvPack(T_Connect *connect,T_NetHead *nethead)
{
char headbuf[HEADPACKLENGTH+1],addr[16];
int i,n;
u_int crc;
char *zbuf;

	n_zero(PARANUM,nethead->para);
	nethead->data=0;
	memset(headbuf,0,sizeof(headbuf));
	i=RecvNet(connect->Socket,headbuf,HEADPACKLENGTH,connect->timeout);
//free SendBuffer
	if(i<HEADPACKLENGTH){
		if(i==TIMEOUTERR) {
			ShowLog(1,"%s:head TIMEOUT %d second's",__FUNCTION__,
				connect->timeout);
			return i;
		}
		ShowLog(1,"RecvPack Head LENERR i=%d,err=%d,%s",i,errno,strerror(errno));
		return LENGERR;
	}
	headbuf[HEADPACKLENGTH]=0;
	i=NetHeadDispack(nethead,headbuf,connect->family[29]);
	if(i!=0) {
		peeraddr(connect->Socket,addr);
		ShowLog(1,"aft NetHeadDispack len=%d,PKGERR %s:%.48s",i, addr,headbuf);
		showpack(1,headbuf,HEADPACKLENGTH);
		return(FORMATERR);
	}
	if(!nethead->T_LEN) return 0;
	i=((connect->CryptFlg&UNDO_ZIP)?nethead->T_LEN:nethead->PKG_LEN)+1;
	n=connect->RecvLen-i;
	if(n<0 || n>SDBC_BLKSZ){
		if( connect->RecvBuffer)
			free(connect->RecvBuffer);
		connect->RecvBuffer=0;
		connect->RecvLen=0;
		connect->RecvBuffer=malloc(i);
		if(!connect->RecvBuffer) return MEMERR;
		connect->RecvLen=i;
	}
	if(!(connect->CryptFlg&UNDO_ZIP) && nethead->T_LEN != nethead->PKG_LEN) {
		zbuf=malloc(nethead->T_LEN);
		if(!zbuf) {
			RecvNet(connect->Socket,connect->RecvBuffer,nethead->T_LEN,3);
			return MEMERR;
		}
	} else zbuf=connect->RecvBuffer;
	i=RecvNet(connect->Socket,zbuf,nethead->T_LEN,3);
	if(i < (nethead->T_LEN)) {
		if(TIMEOUTERR == i) {
			ShowLog(1,"%s:recv body TIMEOUT",__FUNCTION__);
			return i;
		}
		if(zbuf!=connect->RecvBuffer) free(zbuf);
		ShowLog(1,"%s,Recv Body T_LEN=%d i=%d,errno=%d",__FUNCTION__,
					nethead->T_LEN,i,errno);
		free(connect->RecvBuffer);
		connect->RecvBuffer=0;
		connect->RecvLen=0;
		return i<0?SYSERR:LENGERR;
	}
	crc=ssh_crc32((const unsigned char *)zbuf, nethead->T_LEN);
	if((connect->CryptFlg & CHECK_CRC) && (crc != nethead->PKG_CRC)) {
		ShowLog(1,"RecvPack:PKG_CRC=%08X,crc=%08X,PKG_LEN=%d,T_LEN=%d,head=%s",
			nethead->PKG_CRC,crc,nethead->PKG_LEN,nethead->T_LEN,headbuf);
			return CRCERR;
	}
        pack_decode(zbuf, nethead->T_LEN,connect);
	if(zbuf != connect->RecvBuffer) {
		if(nethead->T_LEN<9 || nethead->PKG_LEN != qlz_size_decompressed(zbuf)) {
			ShowLog(1,"unzip error T_LEN=%d,ADDR=%s",nethead->T_LEN, addr);
			return FORMATERR;
		}
		i=qlz_decompress(zbuf,connect->RecvBuffer);
		free(zbuf);
		if(i!=nethead->PKG_LEN) {
		    ShowLog(1,"RecvPack:PKG_LEN=%d,T_LEN=%d,unzip_size=%d",
			nethead->PKG_LEN,nethead->T_LEN,i);
			return LENGERR;
		}
	} 
	connect->RecvBuffer[nethead->PKG_LEN]=0;
	nethead->data=connect->RecvBuffer;
	return 0;
}
예제 #14
0
static int packet_send1(SSH_SESSION *session) {
  unsigned int blocksize = (session->current_crypto ?
      session->current_crypto->out_cipher->blocksize : 8);
  u32 currentlen = buffer_get_len(session->out_buffer) + sizeof(u32);
  char padstring[32] = {0};
  int rc = SSH_ERROR;
  u32 finallen;
  u32 crc;
  u8 padding;

  enter_function();
  ssh_log(session,SSH_LOG_PACKET,"Sending a %d bytes long packet",currentlen);

/* TODO FIXME
#if defined(HAVE_LIBZ) && defined(WITH_LIBZ)
  if (session->current_crypto && session->current_crypto->do_compress_out) {
    if (compress_buffer(session, session->out_buffer) < 0) {
      goto error;
    }
    currentlen = buffer_get_len(session->out_buffer);
  }
#endif
*/
  padding = blocksize - (currentlen % blocksize);
  if (session->current_crypto) {
    ssh_get_random(padstring, padding, 0);
  } else {
    memset(padstring, 0, padding);
  }

  finallen = htonl(currentlen);
  ssh_log(session, SSH_LOG_PACKET,
      "%d bytes after comp + %d padding bytes = %d bytes packet",
      currentlen, padding, ntohl(finallen));

  if (buffer_prepend_data(session->out_buffer, &padstring, padding) < 0) {
    goto error;
  }
  if (buffer_prepend_data(session->out_buffer, &finallen, sizeof(u32)) < 0) {
    goto error;
  }

  crc = ssh_crc32(buffer_get(session->out_buffer) + sizeof(u32),
      buffer_get_len(session->out_buffer) - sizeof(u32));

  if (buffer_add_u32(session->out_buffer, ntohl(crc)) < 0) {
    goto error;
  }

#ifdef DEBUG_CRYPTO
  ssh_print_hexa("Clear packet", buffer_get(session->out_buffer),
      buffer_get_len(session->out_buffer));
#endif

  packet_encrypt(session, buffer_get(session->out_buffer) + sizeof(u32),
      buffer_get_len(session->out_buffer) - sizeof(u32));

#ifdef DEBUG_CRYPTO
  ssh_print_hexa("encrypted packet",buffer_get(session->out_buffer),
      buffer_get_len(session->out_buffer));
#endif
  if (ssh_socket_write(session->socket, buffer_get(session->out_buffer),
      buffer_get_len(session->out_buffer)) == SSH_ERROR) {
    goto error;
  }

  rc = packet_flush(session, 0);
  session->send_seq++;

  if (buffer_reinit(session->out_buffer) < 0) {
    rc = SSH_ERROR;
  }
error:
  leave_function();
  return rc;     /* SSH_OK, AGAIN or ERROR */
}
예제 #15
0
/* a slighty modified packet_read2() for SSH-1 protocol */
static int packet_read1(SSH_SESSION *session) {
  void *packet = NULL;
  int rc = SSH_ERROR;
  int to_be_read;
  u32 padding;
  u32 crc;
  u32 len;

  enter_function();

  if(!session->alive) {
    goto error;
  }

  switch (session->packet_state){
    case PACKET_STATE_INIT:
      memset(&session->in_packet, 0, sizeof(PACKET));

      if (session->in_buffer) {
        if (buffer_reinit(session->in_buffer) < 0) {
          goto error;
        }
      } else {
        session->in_buffer = buffer_new();
        if (session->in_buffer == NULL) {
          goto error;
        }
      }

      rc = ssh_socket_read(session->socket, &len, sizeof(u32));
      if (rc != SSH_OK) {
        goto error;
      }

      rc = SSH_ERROR;

      /* len is not encrypted */
      len = ntohl(len);
      if (len > MAX_PACKET_LEN) {
        ssh_set_error(session, SSH_FATAL,
            "read_packet(): Packet len too high (%u %.8x)", len, len);
        goto error;
      }

      ssh_log(session, SSH_LOG_PACKET, "Reading a %d bytes packet", len);

      session->in_packet.len = len;
      session->packet_state = PACKET_STATE_SIZEREAD;
    case PACKET_STATE_SIZEREAD:
      len = session->in_packet.len;
      /* SSH-1 has a fixed padding lenght */
      padding = 8 - (len % 8);
      to_be_read = len + padding;

      /* it is _not_ possible that to_be_read be < 8. */
      packet = malloc(to_be_read);
      if (packet == NULL) {
        ssh_set_error(session, SSH_FATAL, "Not enough space");
        goto error;
      }

      rc = ssh_socket_read(session->socket, packet, to_be_read);
      if(rc != SSH_OK) {
        SAFE_FREE(packet);
        goto error;
      }
      rc = SSH_ERROR;

      if (buffer_add_data(session->in_buffer,packet,to_be_read) < 0) {
        SAFE_FREE(packet);
        goto error;
      }
      SAFE_FREE(packet);

#ifdef DEBUG_CRYPTO
      ssh_print_hexa("read packet:", buffer_get(session->in_buffer),
          buffer_get_len(session->in_buffer));
#endif
      if (session->current_crypto) {
        /*
         * We decrypt everything, missing the lenght part (which was
         * previously read, unencrypted, and is not part of the buffer
         */
        if (packet_decrypt(session,
              buffer_get(session->in_buffer),
              buffer_get_len(session->in_buffer)) < 0) {
          ssh_set_error(session, SSH_FATAL, "Packet decrypt error");
          goto error;
        }
      }
#ifdef DEBUG_CRYPTO
      ssh_print_hexa("read packet decrypted:", buffer_get(session->in_buffer),
          buffer_get_len(session->in_buffer));
#endif
      ssh_log(session, SSH_LOG_PACKET, "%d bytes padding", padding);
      if(((len + padding) != buffer_get_rest_len(session->in_buffer)) ||
          ((len + padding) < sizeof(u32))) {
        ssh_log(session, SSH_LOG_RARE, "no crc32 in packet");
        ssh_set_error(session, SSH_FATAL, "no crc32 in packet");
        goto error;
      }

      memcpy(&crc,
          buffer_get_rest(session->in_buffer) + (len+padding) - sizeof(u32),
          sizeof(u32));
      buffer_pass_bytes_end(session->in_buffer, sizeof(u32));
      crc = ntohl(crc);
      if (ssh_crc32(buffer_get_rest(session->in_buffer),
            (len + padding) - sizeof(u32)) != crc) {
#ifdef DEBUG_CRYPTO
        ssh_print_hexa("crc32 on",buffer_get_rest(session->in_buffer),
            len + padding - sizeof(u32));
#endif
        ssh_log(session, SSH_LOG_RARE, "Invalid crc32");
        ssh_set_error(session, SSH_FATAL,
            "Invalid crc32: expected %.8x, got %.8x",
            crc,
            ssh_crc32(buffer_get_rest(session->in_buffer),
              len + padding - sizeof(u32)));
        goto error;
      }
      /* pass the padding */
      buffer_pass_bytes(session->in_buffer, padding);
      ssh_log(session, SSH_LOG_PACKET, "The packet is valid");

/* TODO FIXME
#if defined(HAVE_LIBZ) && defined(WITH_LIBZ)
    if(session->current_crypto && session->current_crypto->do_compress_in){
        decompress_buffer(session,session->in_buffer);
    }
#endif
*/
      session->recv_seq++;
      session->packet_state=PACKET_STATE_INIT;

      leave_function();
      return SSH_OK;
  } /* switch */

  ssh_set_error(session, SSH_FATAL,
      "Invalid state into packet_read1(): %d",
      session->packet_state);
error:
  leave_function();
  return rc;
}
예제 #16
0
파일: packet.cpp 프로젝트: lodyagin/shiesh
	/* Insert padding. Initialized to zero in packet_start1() */
	padding = 8 - len % 8;
	if (!send_context.plaintext) {
		cp = buffer_ptr(&outgoing_packet);
		for (i = 0; i < padding; i++) {
			if (i % 4 == 0)
				rnd = arc4random();
			cp[7 - i] = rnd & 0xff;
			rnd >>= 8;
		}
	}
	buffer_consume(&outgoing_packet, 8 - padding);

	/* Add check bytes. */
	checksum = ssh_crc32(buffer_ptr(&outgoing_packet),
	    buffer_len(&outgoing_packet));
	put_u32(buf, checksum);
	buffer_append(&outgoing_packet, buf, 4);

#ifdef PACKET_DEBUG
	fprintf(stderr, "packet_send plain: ");
	buffer_dump(&outgoing_packet);
#endif

	/* Append to output. */
	put_u32(buf, len);
	buffer_append(&output, buf, 4);
	cp = buffer_append_space(&output, buffer_len(&outgoing_packet));
	cipher_crypt(&send_context, cp, buffer_ptr(&outgoing_packet),
	    buffer_len(&outgoing_packet));
예제 #17
0
파일: deattack.c 프로젝트: bmybbs/bmybbs
void crc_update(word32 * a, word32 b)
{
    b ^= *a;
    *a = ssh_crc32((unsigned char *) &b, sizeof(b));
}