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; }
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; }
/* 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); }