Ejemplo n.º 1
0
int
main(int argc, char **argv)
{
    static ARGPARSE_OPTS opts[] = {
    {0} };
    ARGPARSE_ARGS pargs;
    int i, c;
    int state = 0;
    char strbuf[1000];
    int stridx=0;

    pargs.argc = &argc;
    pargs.argv = &argv;
    pargs.flags = 0;

    i18n_init();
    while( arg_parse( &pargs, opts) ) {
	switch( pargs.r_opt ) {
	  default : pargs.err = 2; break;
	}
    }
    if( argc )
	usage(1);


    for(i=0; i < STACKSIZE; i++ )
	stack[i] = NULL;
    stackidx =0;

    while( (c=getc(stdin)) != EOF ) {
	if( !state ) {	/* waiting */
	    if( isdigit(c) ) {
		state = 1;
		ungetc(c, stdin);
		strbuf[0] = '0';
		strbuf[1] = 'x';
		stridx=2;
	    }
	    else if( isspace(c) )
		;
	    else {
		switch(c) {
		  case '+':
		    if( (c=getc(stdin)) == '+' )
			do_inc();
		    else {
			ungetc(c, stdin);
			do_add();
		    }
		    break;
		  case '-':
		    if( (c=getc(stdin)) == '-' )
			do_dec();
		    else if( isdigit(c) || (c >='A' && c <= 'F') ) {
			state = 1;
			ungetc(c, stdin);
			strbuf[0] = '-';
			strbuf[1] = '0';
			strbuf[2] = 'x';
			stridx=3;
		    }
		    else {
			ungetc(c, stdin);
			do_sub();
		    }
		    break;
		  case '*':
		    do_mul();
		    break;
		  case 'm':
		    do_mulm();
		    break;
		  case '/':
		    do_div();
		    break;
		  case '%':
		    do_rem();
		    break;
		  case '^':
		    do_powm();
		    break;
		  case 'I':
		    do_inv();
		    break;
		  case 'G':
		    do_gcd();
		    break;
		  case '>':
		    do_rshift();
		    break;
		  case 'i': /* dummy */
		    if( !stackidx )
			fputs("stack underflow\n", stderr);
		    else {
			mpi_free(stack[stackidx-1]);
			stackidx--;
		    }
		    break;
		  case 'd': /* duplicate the tos */
		    if( !stackidx )
			fputs("stack underflow\n", stderr);
		    else if( stackidx < STACKSIZE ) {
			mpi_free(stack[stackidx]);
			stack[stackidx] = mpi_copy( stack[stackidx-1] );
			stackidx++;
		    }
		    else
			fputs("stack overflow\n", stderr);
		    break;
		  case 'c':
		    for(i=0; i < stackidx; i++ )
			mpi_free(stack[i]), stack[i] = NULL;
		    stackidx = 0;
		    break;
		  case 'p': /* print the tos */
		    if( !stackidx )
			puts("stack is empty");
		    else {
			mpi_print(stdout, stack[stackidx-1], 1 );
			putchar('\n');
		    }
		    break;
		  case 'f': /* print the stack */
		    for( i = stackidx-1 ; i >= 0; i-- ) {
			printf("[%2d]: ", i );
			mpi_print(stdout, stack[i], 1 );
			putchar('\n');
		    }
		    break;
		  default:
		    fputs("invalid operator\n", stderr);
		}
	    }
	}
	else if( state == 1 ) { /* in a number */
	    if( !isxdigit(c) ) { /* store the number */
		state = 0;
		ungetc(c, stdin);
		if( stridx < 1000 )
		    strbuf[stridx] = 0;

		if( stackidx < STACKSIZE ) {
		    if( !stack[stackidx] )
			stack[stackidx] = mpi_alloc(10);
		    if( mpi_fromstr(stack[stackidx], strbuf) )
			fputs("invalid number\n", stderr);
		    else
			stackidx++;
		}
		else
		    fputs("stack overflow\n", stderr);
	    }
	    else { /* store digit */
		if( stridx < 999 )
		    strbuf[stridx++] = c;
		else if( stridx == 999 ) {
		    strbuf[stridx] = 0;
		    fputs("string too large - truncated\n", stderr);
		    stridx++;
		}
	    }
	}

    }
    for(i=0; i < stackidx; i++ )
	mpi_free(stack[i]);
    return 0;
}
Ejemplo n.º 2
0
int
parse_body (char *buffer, int length, struct body_msg *body)
{
  char *tmp = buffer;
  char *end = buffer + length;
  int offset;
  int off;
  char *bodyline;
  char *address;
  uint16_t port = 0;
  size_t keylen;
  struct reg_body *tmp_body = NULL;
  struct id_body *tmp_body1 = NULL;
  struct add_body *tmp_body2 = NULL;
  struct key_body *tmp_body3 = NULL;




/* strip the beginning space */
  for (tmp; ((*tmp == '\n') || (*tmp == '\r'))
       && ((tmp - buffer) < length); tmp++);
  offset = tmp - buffer;
  do
    {
      switch (*tmp)
        {
        case 'U':
        case 'u':
          {
            if (!tmp_body)
              tmp_body = create_reg_body ();
            body->type = BODYREG;
            if (off = check ("USER", 4, tmp, end))
              {
                if (LOG_PARSER)
                  log_info ("Body USER found in %u\n", tmp - buffer);
                offset += off;

                /* find the end of this header */
                offset += find_end (tmp + off, end);

                /* find the user address */
                tmp = tmp + off;
                for (tmp; (*tmp == ' ') && ((tmp) < end); tmp++);

                /* copy it to structure */
                tmp_body->user =
                  (char *) strndup (tmp, buffer + offset - tmp - 1);
                tmp_body->user_len = buffer + offset - tmp - 1;

                if (LOG_PARSER)
                  log_info ("The user is : %s\n", tmp_body->user);
                tmp = buffer + offset;
                break;
              }
          }

        case 'A':
        case 'a':
          {
            if (off = check ("ADDRESS", 7, tmp, end))
              {
                if (!tmp_body)
                  tmp_body = create_reg_body ();
                body->type = BODYREG;
                if (LOG_PARSER)
                  log_info ("Body ADDRESS found in %u\n", tmp - buffer);
                offset += off;

                /* find the end of this header */
                offset += find_end (tmp + off, end);

                /* find the IP address */
                tmp = tmp + off;
                for (tmp; (*tmp == ' ') && ((tmp) < end); tmp++);


                /* copy it to structure */
                tmp_body->ip =
                  (char *) strndup (tmp, buffer + offset - tmp - 1);
                tmp_body->ip_len = buffer + offset - tmp - 1;

                if (LOG_PARSER)
                  log_info ("The IP address is : %s\n", tmp_body->ip);
                tmp = buffer + offset;
                break;
              }
            else if (off = check ("ADDER", 5, tmp, end))
              {
                char *data;
                MPI val = mpi_alloc (0);

                if (!tmp_body2)
                  tmp_body2 = create_add_body ();
                body->type = BODYADD;

                if (LOG_PARSER)
                  log_info ("Body Adder found in %u\n", tmp - buffer);

                offset += off;
                /* find the end of this line */
                offset += find_end (tmp + off, end);

                /* find the adder */
                tmp = tmp + off;
                for (tmp; (*tmp == ' ') && ((tmp) < end); tmp++);
                data = m_alloc_clear (buffer + offset - tmp);
                strncpy (data, tmp, buffer + offset - tmp - 1);

                if (mpi_fromstr (val, data))
                  {
                    mpi_free (val);
                    m_free (data);
                    tmp = buffer + offset;
                    break;
                  }
                tmp_body2->adder[tmp_body2->num] = val;
                (tmp_body2->num)++;
                m_free (data);
                tmp = buffer + offset;
                break;
              }
          }

        case 'P':
        case 'p':
          {
            if (off = check ("PORT", 4, tmp, end))
              {
                if (!tmp_body)
                  tmp_body = create_reg_body ();
                body->type = BODYREG;
                if (LOG_PARSER)
                  log_info ("Body PORT found in %u\n", tmp - buffer);
                offset += off;

                /* find the end of this header */
                offset += find_end (tmp + off, end);

                /* find the user address */
                tmp = tmp + off;
                for (tmp; (*tmp == ' ') && ((tmp) < end); tmp++);
                for (tmp; tmp < (buffer + offset - 1); tmp++)
                  {
                    if ((*tmp - 48) <= 9 && (*tmp - 48) >= 0)
                      port = port * 10 + (*tmp - 48);
                    else
                      {
                        log_error ("Error while changing port to number\n");
                        return 1;
                      }
                  }

                /* copy it to structure */
                tmp_body->port = port;

                if (LOG_PARSER)
                  log_info ("The PORT is : %u\n", port);
                tmp = buffer + offset;
                break;
              }
          }

        case '-':
          {
            if (!tmp_body)
              tmp_body = create_reg_body ();
            body->type = BODYREG;
            if (keylen = check_public_key (tmp, end))
              {
                tmp_body->public_key = (char *) strndup (tmp, keylen);
                tmp_body->pk_len = keylen;

                if (LOG_PARSER)
                  log_info ("We found begin pgp length : %u\n"
                            "%s\n", keylen, strndup (tmp, keylen));
                tmp += (keylen + 1);
              }
          }
          break;

        case 'I':
        case 'i':
          {
            uint32_t address;
            char c;
            if (!tmp_body1)
              tmp_body1 = create_id_body ();
            body->type = BODYID;
            if (off = check ("ID_LIST", 7, tmp, end))
              {
                if (LOG_PARSER)
                  log_info ("Body id list found in %u\n", tmp - buffer);
                offset += off;
                /* find the end of this header */
                offset += find_end (tmp + off, end);

                /* find the id */
                tmp = tmp + off;
                for (tmp; (*tmp == ' ') && ((tmp) < end); tmp++);
                if (sscanf (tmp, "%x%c", &address, &c) == 2)
                  {
                    tmp_body1->id[tmp_body1->num] = address;
                    (tmp_body1->num)++;
                  }
                tmp = buffer + offset;
                break;
              }
          }

        case 'K':
        case 'k':
          {
            int length;
            if (!tmp_body3)
              tmp_body3 = create_key_body ();
            body->type = BODYKEY;
            if (off = check ("KEY", 3, tmp, end))
              {
                if (LOG_PARSER)
                  log_info ("Body key found in %u\n", tmp - buffer);
                offset += off;
                /* find the end of this header */
                offset += find_end (tmp + off, end);

                /* find the key */
                tmp = tmp + off;
                for (tmp; (*tmp == ' ') && ((tmp) < end); tmp++);
                length = buffer + offset - tmp;
                tmp_body3->radmsg = m_alloc (length);
                strncpy (tmp_body3->radmsg, tmp, length - 1);
                tmp_body3->radmsg[length] = '\0';
                tmp_body3->length = length - 1;
                tmp = buffer + offset;
                break;
              }
          }
        default:
          {

            log_error
              ("Other body type is found %c. Dont know what to do in %u\n",
               *tmp, tmp - buffer);
            return 1;
          }
        }
    }
  while (*tmp != '\n' && *tmp != '\r' && tmp < end);

  if (body->type == BODYREG)
    {
      /* check if any field is empty, we need a full one */
      if (!tmp_body->user || !tmp_body->ip || (tmp_body->port == 0)
          || !tmp_body->public_key)
        {

          if (tmp_body->user)
            m_free (tmp_body->user);
          if (tmp_body->ip)
            m_free (tmp_body->ip);
          if (tmp_body->public_key)
            m_free (tmp_body->public_key);
          m_free (tmp_body);
          return 1;
        }
      else
        {

          body->msg.regbody = tmp_body;
          tmp_body = NULL;
          return 0;
        }
    }
  else if (body->type == BODYID)
    {
      body->msg.idbody = tmp_body1;
      tmp_body1 = NULL;
      return 0;
    }
  else if (body->type == BODYADD)
    {
      body->msg.addbody = tmp_body2;
      tmp_body2 = NULL;
      return 0;
    }
  else if (body->type == BODYKEY)
    {
      body->msg.keybody = tmp_body3;
      tmp_body2 = NULL;
      return 0;
    }
  return 1;
}
Ejemplo n.º 3
0
/* Convert the external representation of an integer stored in BUFFER
   with a length of BUFLEN into a newly create MPI returned in
   RET_MPI.  If NBYTES is not NULL, it will receive the number of
   bytes actually scanned after a successful operation.  */
gcry_error_t
gcry_mpi_scan (struct gcry_mpi **ret_mpi, enum gcry_mpi_format format,
               const void *buffer_arg, size_t buflen, size_t *nscanned)
{
  const unsigned char *buffer = (const unsigned char*)buffer_arg;
  struct gcry_mpi *a = NULL;
  unsigned int len;
  int secure = (buffer && gcry_is_secure (buffer));

  if (format == GCRYMPI_FMT_SSH)
    len = 0;
  else
    len = buflen;

  if (format == GCRYMPI_FMT_STD)
    {
      const unsigned char *s = buffer;

      a = secure? mpi_alloc_secure ((len+BYTES_PER_MPI_LIMB-1)
                                    /BYTES_PER_MPI_LIMB)
                : mpi_alloc ((len+BYTES_PER_MPI_LIMB-1)/BYTES_PER_MPI_LIMB);
      if (len)
        {
          a->sign = !!(*s & 0x80);
          if (a->sign)
            {
              /* FIXME: we have to convert from 2compl to magnitude format */
              mpi_free (a);
              return gcry_error (GPG_ERR_INTERNAL);
	    }
          else
            _gcry_mpi_set_buffer (a, s, len, 0);
	}
      if (ret_mpi)
        {
          mpi_normalize ( a );
          *ret_mpi = a;
	}
      else
        mpi_free(a);
      return 0;
    }
  else if (format == GCRYMPI_FMT_USG)
    {
      a = secure? mpi_alloc_secure ((len+BYTES_PER_MPI_LIMB-1)
                                    /BYTES_PER_MPI_LIMB)
                : mpi_alloc ((len+BYTES_PER_MPI_LIMB-1)/BYTES_PER_MPI_LIMB);

      if (len)
        _gcry_mpi_set_buffer (a, buffer, len, 0);
      if (ret_mpi)
        {
          mpi_normalize ( a );
          *ret_mpi = a;
	}
      else
        mpi_free(a);
      return 0;
    }
  else if (format == GCRYMPI_FMT_PGP)
    {
      a = mpi_read_from_buffer (buffer, &len, secure);
      if (nscanned)
        *nscanned = len;
      if (ret_mpi && a)
        {
          mpi_normalize (a);
          *ret_mpi = a;
	}
      else if (a)
        {
          mpi_free(a);
          a = NULL;
        }
      return a? 0 : gcry_error (GPG_ERR_INV_OBJ);
    }
  else if (format == GCRYMPI_FMT_SSH)
    {
      const unsigned char *s = buffer;
      size_t n;

      /* This test is not strictly necessary and an assert (!len)
         would be sufficient.  We keep this test in case we later
         allow the BUFLEN argument to act as a sanitiy check.  Same
         below. */
      if (len && len < 4)
        return gcry_error (GPG_ERR_TOO_SHORT);

      n = (s[0] << 24 | s[1] << 16 | s[2] << 8 | s[3]);
      s += 4;
      if (len)
        len -= 4;
      if (len && n > len)
        return gcry_error (GPG_ERR_TOO_LARGE);

      a = secure? mpi_alloc_secure ((n+BYTES_PER_MPI_LIMB-1)
                                    /BYTES_PER_MPI_LIMB)
                : mpi_alloc ((n+BYTES_PER_MPI_LIMB-1)/BYTES_PER_MPI_LIMB);
      if (n)
        {
          a->sign = !!(*s & 0x80);
          if (a->sign)
            {
              /* FIXME: we have to convert from 2compl to magnitude format */
              mpi_free(a);
              return gcry_error (GPG_ERR_INTERNAL);
	    }
          else
            _gcry_mpi_set_buffer( a, s, n, 0 );
	}
      if (nscanned)
        *nscanned = n+4;
      if (ret_mpi)
        {
          mpi_normalize ( a );
          *ret_mpi = a;
        }
      else
        mpi_free(a);
      return 0;
    }
  else if (format == GCRYMPI_FMT_HEX)
    {
      /* We can only handle C strings for now.  */
      if (buflen)
        return gcry_error (GPG_ERR_INV_ARG);

      a = secure? mpi_alloc_secure (0) : mpi_alloc(0);
      if (mpi_fromstr (a, (const char *)buffer))
        {
          mpi_free (a);
          return gcry_error (GPG_ERR_INV_OBJ);
        }
      if (ret_mpi)
        {
          mpi_normalize ( a );
          *ret_mpi = a;
	}
      else
        mpi_free(a);
      return 0;
    }
  else
    return gcry_error (GPG_ERR_INV_ARG);
}