Exemplo n.º 1
0
/****************
 * Copy data from INP to OUT and do some escaping if requested.
 * md is updated as required by rfc2440
 */
int
copy_clearsig_text( IOBUF out, IOBUF inp, gcry_md_hd_t md,
		    int escape_dash, int escape_from)
{
    unsigned int maxlen;
    byte *buffer = NULL;    /* malloced buffer */
    unsigned int bufsize;   /* and size of this buffer */
    unsigned int n;
    int truncated = 0;
    int pending_lf = 0;

   if( !escape_dash )
	escape_from = 0;

    write_status_begin_signing (md);

    for(;;) {
	maxlen = MAX_LINELEN;
	n = iobuf_read_line( inp, &buffer, &bufsize, &maxlen );
	if( !maxlen )
	    truncated++;

	if( !n )
	    break; /* read_line has returned eof */

	/* update the message digest */
	if( escape_dash ) {
	    if( pending_lf ) {
		gcry_md_putc ( md, '\r' );
		gcry_md_putc ( md, '\n' );
	    }
	    gcry_md_write ( md, buffer,
                            len_without_trailing_chars (buffer, n, " \t\r\n"));
	}
	else
            gcry_md_write ( md, buffer, n );
	pending_lf = buffer[n-1] == '\n';

	/* write the output */
	if(    ( escape_dash && *buffer == '-')
	    || ( escape_from && n > 4 && !memcmp(buffer, "From ", 5 ) ) ) {
	    iobuf_put( out, '-' );
	    iobuf_put( out, ' ' );
	}

#if  0 /*defined(HAVE_DOSISH_SYSTEM)*/
	/* We don't use this anymore because my interpretation of rfc2440 7.1
	 * is that there is no conversion needed.  If one decides to
	 * clearsign a unix file on a DOS box he will get a mixed line endings.
	 * If at some point it turns out, that a conversion is a nice feature
	 * we can make an option out of it.
	 */
	/* make sure the lines do end in CR,LF */
	if( n > 1 && ( (buffer[n-2] == '\r' && buffer[n-1] == '\n' )
			    || (buffer[n-2] == '\n' && buffer[n-1] == '\r'))) {
	    iobuf_write( out, buffer, n-2 );
	    iobuf_put( out, '\r');
	    iobuf_put( out, '\n');
	}
	else if( n && buffer[n-1] == '\n' ) {
	    iobuf_write( out, buffer, n-1 );
	    iobuf_put( out, '\r');
	    iobuf_put( out, '\n');
	}
	else
	    iobuf_write( out, buffer, n );

#else
	iobuf_write( out, buffer, n );
#endif
    }

    /* at eof */
    if( !pending_lf ) { /* make sure that the file ends with a LF */
	iobuf_writestr( out, LF );
	if( !escape_dash )
	    gcry_md_putc( md, '\n' );
    }

    if( truncated )
	log_info(_("input line longer than %d characters\n"), MAX_LINELEN );

    return 0; /* okay */
}
Exemplo n.º 2
0
CURLcode
curl_easy_perform(CURL *curl)
{
  int rc;
  CURLcode err=CURLE_OK;
  const char *errstr=NULL;
  char *proxy=NULL;
  struct http_srv srv;

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

  /* Emulate the libcurl proxy behavior.  If the calling program set a
     proxy, use it.  If it didn't set a proxy or set it to NULL, check
     for one in the environment.  If the calling program explicitly
     set a null-string proxy the http code doesn't use a proxy at
     all. */

  if(curl->proxy)
    proxy=curl->proxy;
  else
    proxy=getenv(HTTP_PROXY_ENV);

  if(curl->srvtag)
    srv.srvtag=curl->srvtag;

  if(curl->flags.verbose)
    {
      fprintf(curl->errors,"* HTTP proxy is \"%s\"\n",proxy?proxy:"null");
      fprintf(curl->errors,"* HTTP URL is \"%s\"\n",curl->url);
      if(srv.srvtag)
	fprintf(curl->errors,
		"* SRV tag is \"%s\": host and port may be overridden\n",
		srv.srvtag);
      fprintf(curl->errors,"* HTTP auth is \"%s\"\n",
	      curl->auth?curl->auth:"null");
      fprintf(curl->errors,"* HTTP method is %s\n",
	      curl->flags.post?"POST":"GET");
    }

  if(curl->flags.post)
    {
      rc=http_open(&curl->hd,HTTP_REQ_POST,curl->url,curl->auth,0,proxy,
		   &srv,curl->headers?curl->headers->list:NULL);
      if(rc==0)
	{
	  char content_len[50];
	  unsigned int post_len=strlen(curl->postfields);

	  if(curl->flags.verbose && srv.used_server && srv.used_port)
	    fprintf (curl->errors, "* HTTP host:port post-SRV is \"%s:%hu\"\n",
		     srv.used_server, srv.used_port);

	  iobuf_writestr(curl->hd.fp_write,
			 "Content-Type: application/x-www-form-urlencoded\r\n");
	  sprintf(content_len,"Content-Length: %u\r\n",post_len);

	  iobuf_writestr(curl->hd.fp_write,content_len);

	  http_start_data(&curl->hd);
	  iobuf_write(curl->hd.fp_write,curl->postfields,post_len);
	  rc=http_wait_response(&curl->hd,&curl->status);
	  if(rc==0 && curl->flags.failonerror && curl->status>=300)
	    err=CURLE_HTTP_RETURNED_ERROR;
	}
    }
  else
    {
      rc=http_open(&curl->hd,HTTP_REQ_GET,curl->url,curl->auth,0,proxy,
		   &srv,curl->headers?curl->headers->list:NULL);
      if(rc==0)
	{
	  if(curl->flags.verbose && srv.used_server && srv.used_port)
	    fprintf (curl->errors, "* HTTP host:port post-SRV is \"%s:%hu\"\n",
		     srv.used_server, srv.used_port);

	  rc=http_wait_response(&curl->hd,&curl->status);
	  if(rc==0)
	    {
	      if(curl->flags.failonerror && curl->status>=300)
		err=CURLE_HTTP_RETURNED_ERROR;
	      else
		{
		  unsigned int maxlen=1024,buflen,len;
		  byte *line=NULL;

		  while((len=iobuf_read_line(curl->hd.fp_read,
					     &line,&buflen,&maxlen)))
		    {
		      size_t ret;

		      maxlen=1024;

		      ret=(curl->writer)(line,len,1,curl->file);
		      if(ret!=len)
			{
			  err=CURLE_WRITE_ERROR;
			  break;
			}
		    }

		  xfree(line);
		  http_close(&curl->hd);
		}
	    }
	  else
	    http_close(&curl->hd);
	}
    }

  free (srv.used_server);

  switch(rc)
    {
    case 0:
      break;

    case G10ERR_INVALID_URI:
      err=CURLE_UNSUPPORTED_PROTOCOL;
      break;

    case G10ERR_NETWORK:
      errstr=strerror(errno);
      err=CURLE_COULDNT_CONNECT;
      break;

    default:
      errstr=g10_errstr(rc);
      err=CURLE_COULDNT_CONNECT;
      break;
    }
      
  return handle_error(curl,err,errstr);
}
Exemplo n.º 3
0
/* Returns a keyrec (which must be freed) once a key is complete, and
   NULL otherwise.  Call with a NULL keystring once key parsing is
   complete to return any unfinished keys. */
static struct keyrec *
parse_keyrec(char *keystring)
{
  /* FIXME: Remove the static and put the data into the parms we use
     for the caller anyway.  */
  static struct keyrec *work=NULL;
  struct keyrec *ret=NULL;
  char *record;
  int i;

  if(keystring==NULL)
    {
      if(work==NULL)
	return NULL;
      else if(work->desc.mode==KEYDB_SEARCH_MODE_NONE)
	{
	  xfree(work);
	  return NULL;
	}
      else
	{
	  ret=work;
	  work=NULL;
	  return ret;
	}
    }

  if(work==NULL)
    {
      work=xmalloc_clear(sizeof(struct keyrec));
      work->uidbuf=iobuf_temp();
    }

  trim_trailing_ws (keystring, strlen (keystring));

  if((record=strsep(&keystring,":"))==NULL)
    return ret;

  if(ascii_strcasecmp("pub",record)==0)
    {
      char *tok;
      gpg_error_t err;

      if(work->desc.mode)
	{
	  ret=work;
	  work=xmalloc_clear(sizeof(struct keyrec));
	  work->uidbuf=iobuf_temp();
	}

      if((tok=strsep(&keystring,":"))==NULL)
	return ret;

      err = classify_user_id (tok, &work->desc, 1);
      if (err || (work->desc.mode    != KEYDB_SEARCH_MODE_SHORT_KID
                  && work->desc.mode != KEYDB_SEARCH_MODE_LONG_KID
                  && work->desc.mode != KEYDB_SEARCH_MODE_FPR16
                  && work->desc.mode != KEYDB_SEARCH_MODE_FPR20))
	{
	  work->desc.mode=KEYDB_SEARCH_MODE_NONE;
	  return ret;
	}

      /* Note all items after this are optional.  This allows us to
         have a pub line as simple as pub:keyid and nothing else. */

      work->lines++;

      if((tok=strsep(&keystring,":"))==NULL)
	return ret;

      work->type=atoi(tok);

      if((tok=strsep(&keystring,":"))==NULL)
	return ret;

      work->size=atoi(tok);

      if((tok=strsep(&keystring,":"))==NULL)
	return ret;

      if(atoi(tok)<=0)
	work->createtime=0;
      else
	work->createtime=atoi(tok);

      if((tok=strsep(&keystring,":"))==NULL)
	return ret;

      if(atoi(tok)<=0)
	work->expiretime=0;
      else
	{
	  work->expiretime=atoi(tok);
	  /* Force the 'e' flag on if this key is expired. */
	  if(work->expiretime<=make_timestamp())
	    work->flags|=4;
	}

      if((tok=strsep(&keystring,":"))==NULL)
	return ret;

      while(*tok)
	switch(*tok++)
	  {
	  case 'r':
	  case 'R':
	    work->flags|=1;
	    break;

	  case 'd':
	  case 'D':
	    work->flags|=2;
	    break;

	  case 'e':
	  case 'E':
	    work->flags|=4;
	    break;
	  }
    }
  else if(ascii_strcasecmp("uid",record)==0 && work->desc.mode)
    {
      char *userid,*tok,*decoded;

      if((tok=strsep(&keystring,":"))==NULL)
	return ret;

      if(strlen(tok)==0)
	return ret;

      userid=tok;

      /* By definition, de-%-encoding is always smaller than the
         original string so we can decode in place. */

      i=0;

      while(*tok)
	if(tok[0]=='%' && tok[1] && tok[2])
	  {
            int c;

	    userid[i] = (c=hextobyte(&tok[1])) == -1 ? '?' : c;
	    i++;
	    tok+=3;
	  }
	else
	  userid[i++]=*tok++;

      /* We don't care about the other info provided in the uid: line
         since no keyserver supports marking userids with timestamps
         or revoked/expired/disabled yet. */

      /* No need to check for control characters, as utf8_to_native
	 does this for us. */

      decoded=utf8_to_native(userid,i,0);
      if(strlen(decoded)>opt.screen_columns-10)
	decoded[opt.screen_columns-10]='\0';
      iobuf_writestr(work->uidbuf,decoded);
      xfree(decoded);
      iobuf_writestr(work->uidbuf,"\n\t");
      work->lines++;
    }

  /* Ignore any records other than "pri" and "uid" for easy future
     growth. */

  return ret;
}