コード例 #1
0
ファイル: netfns.c プロジェクト: DanielTillett/libu8
U8_EXPORT u8_string u8_host_primary(u8_string hostname)
{
  struct hostent *h=u8_gethostbyname(hostname,-1);
  if (h==NULL) return NULL;
  else {
    u8_string pname=u8_fromlibc(h->h_name);
    u8_free(h);
    return pname;}
}
コード例 #2
0
U8_EXPORT void u8_contour_free(u8_contour c,void *ptr)
{
  u8_contour scan=c;
  while (scan) {
    if (scan->u8c_n_blocks) {
      void **blocks=scan->u8c_blocks;
      int i=scan->u8c_n_blocks-1;
      /* Intentionally scanning backwards because that seems like a more
         likely case. */
      while (i>=0)
        if (blocks[i]==ptr) {
          blocks[i]=NULL; u8_free(ptr);
          return;}
        else i--;}
    scan=scan->u8c_outer_contour;}
  /* Should this err or warn? */
  u8_free(ptr);
}
コード例 #3
0
ファイル: netfns.c プロジェクト: DanielTillett/libu8
U8_EXPORT u8_string u8_canonical_addr(u8_string spec)
{
  u8_byte _hostname[128], *hostname=_hostname; int portno;
  u8_string result;
  hostname=u8_parse_addr(spec,&portno,hostname,128);
  if (strchr(hostname,':'))
    result=u8_mkstring("%s::%d",hostname,portno);
  else result=u8_mkstring("%s:%d",hostname,portno);
  if (hostname!=_hostname) u8_free(hostname);
  return result;
}
コード例 #4
0
ファイル: netfns.c プロジェクト: DanielTillett/libu8
U8_EXPORT struct hostent *u8_gethostbyname(u8_string hname,int type)
{
  char *name=u8_tolibc(hname);
  struct hostent *fetched, *copied;
  char _buf[1024], *buf=_buf;
  int bufsiz=0, herrno=0, retval;
#if HAVE_GETHOSTBYNAME2_R
  struct hostent _fetched, *result; fetched=&_fetched;
  if (type>0)
    retval=
      gethostbyname2_r(name,type,fetched,buf,1024,&result,&herrno);
  else retval=gethostbyname_r(name,fetched,buf,1024,&result,&herrno);
  while (retval==ERANGE) {
    if (bufsiz) bufsiz=2048; else {u8_free(buf); bufsiz=bufsiz*2;}
    buf=u8_malloc(bufsiz);
    if (type>0)
      retval=
	gethostbyname2_r(name,type,fetched,buf,1024,&result,&herrno);
    else retval=gethostbyname_r(name,fetched,buf,1024,&result,&herrno);}
  if (result==NULL) {
    if (bufsiz) u8_free(buf);
    u8_graberr(herrno,"u8_gethostbyname",u8_strdup(hname));
    return NULL;}
  copied=((fetched==NULL) ? (NULL) :(copy_hostent(fetched)));
  if (bufsiz) u8_free(buf);
#else
  u8_lock_mutex(&netfns_lock);
  fetched=gethostbyname(name);
  if (fetched==NULL) {
    u8_seterr(UnknownHost,"u8_gethostbyname",name);
    u8_unlock_mutex(&netfns_lock);
    return NULL;}
  copied=copy_hostent(fetched);
  u8_unlock_mutex(&netfns_lock);
#endif
  u8_free(name);
  return copied;
}
コード例 #5
0
ファイル: netfns.c プロジェクト: DanielTillett/libu8
U8_EXPORT u8_string u8_parse_addr
    (u8_string spec,int *portp,u8_byte *result,ssize_t buflen)
{
  u8_byte *split=strchr(spec,'@'); int len=strlen(spec);
  if ((result==NULL)||(buflen<0)) {
    buflen=len+1; result=u8_malloc(buflen); }
  if (split==spec) {
    *portp=0; strcpy(result,spec+1);
    return result;}
  else if (split) {
    int portlen=split-spec, hostlen=len-(portlen+1);
    u8_byte _portspec[32], *portspec;
    if (portlen>31) portspec=u8_malloc(1+(split-spec));
    else portspec=_portspec;
    strncpy(portspec,spec,portlen); portspec[portlen]='\0';
    *portp=u8_get_portno(portspec);
    if (portspec!=_portspec) u8_free(portspec);
    if (hostlen>=buflen) result=u8_malloc(hostlen+1);
    strncpy(result,split+1,hostlen); result[hostlen]='\0';
    return result;}
  else if ((split=strrchr(spec,':'))) {
    /* We search backwards for the colon because we want to handle
       IPv6 addresses with double colons separating octets (?) */
    if ((split[1]=='\0')||((split>spec)&&(split[-1]==':'))) {
      *portp=0; strcpy(result,spec+1);
      return result;}
    *portp=u8_get_portno(split+1);
    if (buflen<(split-spec)) {
      buflen=(split-spec)+1; result=u8_malloc(buflen);}
    strncpy(result,spec,split-spec);
    if (result[split-spec-1]==':')
      /* Accept a double colon before the port number, in case the address
	 portion is an IPV6 numeric address. */
      result[split-spec-1]='\0';
    else result[split-spec]='\0';
    return result;}
  else return NULL;
}
コード例 #6
0
U8_EXPORT ssize_t u8_cryptic
(int do_encrypt,const char *cname,
 const unsigned char *key,int keylen,
 const unsigned char *iv,int ivlen,
 u8_block_reader reader,u8_block_writer writer,
 void *readstate,void *writestate,
 u8_context caller)
{
  if (strncasecmp(cname,"rsa",3)==0) {
    ENGINE *eng=ENGINE_get_default_RSA();
    EVP_PKEY _pkey, *pkey; EVP_PKEY_CTX *ctx; 
    int pubkeyin=(strncasecmp(cname,"rsapub",6)==0);
    const unsigned char *scankey=key;
    struct U8_BYTEBUF bb;
    int retval=-1;
    if (pubkeyin) pkey=d2i_PUBKEY(NULL,&scankey,keylen);
    else pkey=d2i_PrivateKey((EVP_PKEY_RSA),NULL,&scankey,keylen);
    if (!(pkey)) ctx=NULL;
    else {
#if (OPENSSL_VERSION_NUMBER>=0x1000204fL)
      ctx=EVP_PKEY_CTX_new(pkey,eng);
#else
      ctx=EVP_PKEY_CTX_new(pkey,NULL);
#endif
    }
    if (ctx) {
      memset(&bb,0,sizeof(bb));
      bb.u8_direction=u8_output_buffer;
      bb.u8_buf=bb.u8_ptr=(u8_byte *)u8_malloc(1024);
      bb.u8_lim=(u8_byte *)(bb.u8_buf+1024);
      bb.u8_growbuf=1;
      fill_bytebuf(&bb,reader,readstate);}
    if (!(ctx)) {}
    else if ((pubkeyin)?
	     ((do_encrypt)?((retval=EVP_PKEY_encrypt_init(ctx))<0):
	      ((retval=EVP_PKEY_verify_recover_init(ctx))<0)):
	     ((do_encrypt)?((retval=EVP_PKEY_sign_init(ctx))<0):
	      ((retval=EVP_PKEY_decrypt_init(ctx))<0))) {}
    else {
      unsigned char *in=bb.u8_buf; size_t inlen=bb.u8_ptr-bb.u8_buf;
      unsigned char *out=NULL; size_t outlen;
      if (pubkeyin) {
	if (do_encrypt) retval=EVP_PKEY_encrypt(ctx,NULL,&outlen,in,inlen);
	else retval=EVP_PKEY_verify_recover(ctx,NULL,&outlen,in,inlen);}
      else if (do_encrypt) retval=EVP_PKEY_sign(ctx,NULL,&outlen,in,inlen);
      else retval=EVP_PKEY_decrypt(ctx,NULL,&outlen,in,inlen);
      if (retval<0) {}
      else if ((out=u8_malloc(outlen))==NULL) {}
      else if (pubkeyin) {
	if (do_encrypt) retval=EVP_PKEY_encrypt(ctx,out,&outlen,in,inlen);
	else retval=EVP_PKEY_verify_recover(ctx,out,&outlen,in,inlen);}
      else if (do_encrypt) retval=EVP_PKEY_sign(ctx,out,&outlen,in,inlen);
      else retval=EVP_PKEY_decrypt(ctx,out,&outlen,in,inlen);
      if (retval<0) {}
      else retval=writer(out,outlen,writestate);
      if (out) u8_free(out);}
    u8_free(bb.u8_buf);
    if (retval<0) {
      unsigned long err=ERR_get_error(); char buf[512];
      buf[0]='\0'; ERR_error_string_n(err,buf,512);
      u8_seterr(u8_InternalCryptoError,OPENSSL_CRYPTIC,u8_fromlibc((char *)buf));
      ERR_clear_error();}
    if (ctx) EVP_PKEY_CTX_free(ctx);
    if (pkey)  EVP_PKEY_free(pkey);
    return retval;}
  else {
    EVP_CIPHER_CTX ctx;
    int inlen, outlen, retval=0;
    ssize_t totalout=0, totalin=0;
    unsigned char inbuf[1024], outbuf[1024+EVP_MAX_BLOCK_LENGTH];
    const EVP_CIPHER *cipher=((cname)?(EVP_get_cipherbyname(cname)):
			      (EVP_aes_128_cbc()));

    if (cipher) {
      int needkeylen=EVP_CIPHER_key_length(cipher);
      int needivlen=EVP_CIPHER_iv_length(cipher);
      int blocksize=EVP_CIPHER_block_size(cipher);
      if (blocksize>1024) blocksize=1024;
      u8_log(CRYPTO_LOGLEVEL,OPENSSL_CRYPTIC,
	     " %s cipher=%s, keylen=%d/%d, ivlen=%d/%d, blocksize=%d\n",
	     ((do_encrypt)?("encrypt"):("decrypt")),
	     cname,keylen,needkeylen,ivlen,needivlen,blocksize);

      if ((needivlen)&&(ivlen)&&(ivlen!=needivlen))
	return u8_reterr(u8_BadCryptoIV,
			 ((caller)?(caller):(OPENSSL_CRYPTIC)),
			 u8_mkstring("%d!=%d(%s)",ivlen,needivlen,cname));

      memset(&ctx,0,sizeof(ctx));

      EVP_CIPHER_CTX_init(&ctx);

      retval=EVP_CipherInit(&ctx, cipher, NULL, NULL, do_encrypt);
      if (retval==0)
	return u8_reterr(u8_CipherInit_Failed,
			 ((caller)?(caller):(OPENSSL_CRYPTIC)),
			 u8_strdup(cname));

      retval=EVP_CIPHER_CTX_set_key_length(&ctx,keylen);
      if (retval==0)
	return u8_reterr(u8_BadCryptoKey,
			 ((caller)?(caller):(OPENSSL_CRYPTIC)),
			 u8_mkstring("%d!=%d(%s)",keylen,needkeylen,cname));

      if ((needivlen)&&(ivlen!=needivlen))
	return u8_reterr(u8_BadCryptoIV,
			 ((caller)?(caller):(OPENSSL_CRYPTIC)),
			 u8_mkstring("%d!=%d(%s)",ivlen,needivlen,cname));

      retval=EVP_CipherInit(&ctx, cipher, key, iv, do_encrypt);
      if (retval==0)
	return u8_reterr(u8_CipherInit_Failed,
			 ((caller)?(caller):(OPENSSL_CRYPTIC)),
			 u8_strdup(cname));

      while (1) {
	inlen = reader(inbuf,blocksize,readstate);
	if (inlen <= 0) {
	  u8_log(CRYPTO_LOGLEVEL,OPENSSL_CRYPTIC,
		 "Finished %s(%s) with %ld in, %ld out",
		 ((do_encrypt)?("encrypt"):("decrypt")),
		 cname,totalin,totalout);
	  break;}
	else totalin=totalin+inlen;
	if (!(EVP_CipherUpdate(&ctx,outbuf,&outlen,inbuf,inlen))) {
	  char *details=u8_malloc(256);
	  unsigned long err=ERR_get_error();
	  ERR_error_string_n(err,details,256);
	  EVP_CIPHER_CTX_cleanup(&ctx);
	  return u8_reterr(u8_InternalCryptoError,
			   ((caller)?(caller):((u8_context)"u8_cryptic")),
			   details);}
	else {
	  u8_log(CRYPTO_LOGLEVEL,OPENSSL_CRYPTIC,
		 "%s(%s) consumed %d/%ld bytes, emitted %d/%ld bytes"
		 " in=<%v>\n out=<%v>",
		 ((do_encrypt)?("encrypt"):("decrypt")),cname,
		 inlen,totalin,outlen,totalout+outlen,
		 inbuf,inlen,outbuf,outlen);
	  writer(outbuf,outlen,writestate);
	  totalout=totalout+outlen;}}
      if (!(EVP_CipherFinal(&ctx,outbuf,&outlen))) {
	char *details=u8_malloc(256);
	unsigned long err=ERR_get_error();
	ERR_error_string_n(err,details,256);
	EVP_CIPHER_CTX_cleanup(&ctx);
	return u8_reterr(u8_InternalCryptoError,
			 ((caller)?(caller):(OPENSSL_CRYPTIC)),
			 details);}
      else {
	writer(outbuf,outlen,writestate);
	u8_log(CRYPTO_LOGLEVEL,OPENSSL_CRYPTIC,
	       "%s(%s) done after consuming %ld/%ld bytes, emitting %ld/%ld bytes"
	       "\n final out=<%v>",
	       ((do_encrypt)?("encrypt"):("decrypt")),cname,
	       inlen,totalin,outlen,totalout+outlen,
	       outbuf,outlen);
	EVP_CIPHER_CTX_cleanup(&ctx);
	totalout=totalout+outlen;
	return totalout;}}
    else {
      char *details=u8_malloc(256);
      unsigned long err=ERR_get_error();
      ERR_error_string_n(err,details,256);
      return u8_reterr("Unknown cipher",
		       ((caller)?(caller):((u8_context)"u8_cryptic")),
		       details);}
  }
}
コード例 #7
0
ファイル: netfns.c プロジェクト: DanielTillett/libu8
U8_EXPORT u8_socket u8_connect_x(u8_string spec,u8_string *addrp)
{
  u8_byte _hostname[128], *hostname=_hostname; int portno=-1;
  long socket_id;
  hostname=u8_parse_addr(spec,&portno,hostname,128);
  if (portno<0) return ((u8_socket)(-1));
  else if (!(hostname)) return ((u8_socket)(-1));
  else if (portno) {
    struct sockaddr_in sockaddr;
    int addr_len, family=AF_INET;
    /* Lookup the host */
    char **addrs=u8_lookup_host(hostname,&addr_len,&family), **scan=addrs;
    if (addrs==NULL) {
      if (hostname!=_hostname) u8_free(hostname);
      return -1;}
    /* Get a socket */
    if ((socket_id=socket(family,SOCK_STREAM,0))<0) {
      u8_graberr(-1,"u8_connect:socket",u8_strdup(spec));
      u8_free(addrs);
      if (hostname!=_hostname) u8_free(hostname);
      return ((u8_socket)(-1));}
#if 0
    if (timeout>0) {
      struct timeval tv;
      tv.tv_sec=timeout/1000; tv.tv_usec=(timeout%1000)*1000;
      setsockopt(socket_id,level,SO_SNDTIMEO,(void *)&tv,sizeof(struct timeval));
      tv.tv_sec=timeout/1000; tv.tv_usec=(timeout%1000)*1000;
      setsockopt(socket_id,SO_RCVTIME0,(void *)&tv,sizeof(struct timeval));}
    setsockopt(socket_id,SO_NOSIGPIPE,(void *)1,sizeof(int));
#endif
    while (*scan) {
      char *addr=*scan++;
      sockaddr.sin_port=htons((short)portno);
      memcpy(&(sockaddr.sin_addr),addr,addr_len);
      sockaddr.sin_family=family;
      if (connect(socket_id,saddr(sockaddr),sizeof(struct sockaddr_in))<0) 
	if (*scan==NULL) {
	  close(socket_id);
	  u8_free(addrs);
	  if (hostname!=_hostname) u8_free(hostname);
	  u8_graberr(-1,"u8_connect:connect",u8_strdup(spec));
	  return ((u8_socket)(-1));}
	else errno=0; /* Try the next address */
      else {
	if (addrp) *addrp=u8_sockaddr_string((struct sockaddr *)&sockaddr);
	if (hostname!=_hostname) u8_free(hostname);
	u8_free(addrs);
	return (u8_socket)socket_id;}}
    u8_free(addrs);
    if (hostname!=_hostname) u8_free(hostname);
    return ((u8_socket)(-1));}
  else {
#if HAVE_SYS_UN_H
    struct sockaddr_un sockaddr;
    if ((socket_id=socket(PF_LOCAL,SOCK_STREAM,0))<0) {
      u8_graberr(-1,"u8_connect:socket",u8_strdup(spec));
      if (hostname!=_hostname) u8_free(hostname);
      return -1;}
    sockaddr.sun_family=AF_UNIX;
    strcpy(sockaddr.sun_path,hostname);
    if (connect(socket_id,saddr(sockaddr),sizeof(struct sockaddr_un))<0) {
      close(socket_id);
      u8_graberr(-1,"u8_connect:connect",u8_strdup(spec));
      if (hostname!=_hostname) u8_free(hostname);
      return ((u8_socket)(-1));}
    else return (u8_socket)socket_id;
#else
    u8_seterr(NoFileSockets,"u8_connect",NULL);
    return ((u8_socket)(-1));
#endif
  }
}