Ejemplo n.º 1
0
void crypto_free(struct ssh_crypto_struct *crypto){
  if (crypto == NULL) {
    return;
  }

  SAFE_FREE(crypto->server_pubkey);

  cipher_free(crypto->in_cipher);
  cipher_free(crypto->out_cipher);

  bignum_free(crypto->e);
  bignum_free(crypto->f);
  bignum_free(crypto->x);
  bignum_free(crypto->y);
  bignum_free(crypto->k);
  /* lot of other things */

#ifdef WITH_LIBZ
  if (crypto->compress_out_ctx &&
      (deflateEnd(crypto->compress_out_ctx) != 0)) {
    inflateEnd(crypto->compress_out_ctx);
  }
  if (crypto->compress_in_ctx &&
      (deflateEnd(crypto->compress_in_ctx) != 0)) {
    inflateEnd(crypto->compress_in_ctx);
  }
#endif

  /* i'm lost in my own code. good work */
  memset(crypto,0,sizeof(*crypto));

  SAFE_FREE(crypto);
}
Ejemplo n.º 2
0
Archivo: bignum.c Proyecto: rtfb/82k
void bignum_init_base_convert(size_t size, int base) {
    bignum multiplier;
    bignum_init(&multiplier);
    bignum_from_int(&multiplier, 1);
    mul_lut = malloc(size * sizeof(bignum));
    mul_lut_size = size;
    for (int i = 0; i < size; ++i) {
        bignum_init(&mul_lut[i]);
        bignum_copy(&mul_lut[i], &multiplier);
        bignum_mul_int(&multiplier, base);
    }
    bignum_free(&multiplier);

    bignum sum;
    bignum_init(&sum);
    for (int i = 0; i < SUMSZ; ++i) {
        for (int j = 0; j < 256; ++j) {
            int m = i*8;
            bignum_from_int(&sum, 0);
            for (uint8_t mask = 1; mask != 0; mask <<= 1) {
                if (j & mask) {
                    bignum_add(&sum, &mul_lut[m]);
                }
                ++m;
            }
            bignum_init(&sum_lut[i][j]);
            bignum_copy(&sum_lut[i][j], &sum);
        }
    }
    bignum_free(&sum);
}
Ejemplo n.º 3
0
/* returns 1 if the modulus of k1 is < than the one of k2 */
static int modulus_smaller(ssh_public_key k1, ssh_public_key k2){
    bignum n1;
    bignum n2;
    int res;
#ifdef HAVE_LIBGCRYPT
    gcry_sexp_t sexp;
    sexp=gcry_sexp_find_token(k1->rsa_pub,"n",0);
    n1=gcry_sexp_nth_mpi(sexp,1,GCRYMPI_FMT_USG);
    gcry_sexp_release(sexp);
    sexp=gcry_sexp_find_token(k2->rsa_pub,"n",0);
    n2=gcry_sexp_nth_mpi(sexp,1,GCRYMPI_FMT_USG);
    gcry_sexp_release(sexp);
#elif defined HAVE_LIBCRYPTO
    n1=k1->rsa_pub->n;
    n2=k2->rsa_pub->n;
#endif
    if(bignum_cmp(n1,n2)<0)
        res=1;
    else
        res=0;
#ifdef HAVE_LIBGCRYPT
    bignum_free(n1);
    bignum_free(n2);
#endif
    return res;
    
}
Ejemplo n.º 4
0
char *my_gcry_bn2dec(bignum bn) {
  bignum bndup, num, ten;
  char *ret;
  int count, count2;
  int size, rsize;
  char decnum;

  size = gcry_mpi_get_nbits(bn) * 3;
  rsize = size / 10 + size / 1000 + 2;

  ret = malloc(rsize + 1);
  if (ret == NULL) {
    return NULL;
  }

  if (!gcry_mpi_cmp_ui(bn, 0)) {
    strcpy(ret, "0");
  } else {
    ten = bignum_new();
    if (ten == NULL) {
      SAFE_FREE(ret);
      return NULL;
    }

    num = bignum_new();
    if (num == NULL) {
      SAFE_FREE(ret);
      bignum_free(ten);
      return NULL;
    }

    for (bndup = gcry_mpi_copy(bn), bignum_set_word(ten, 10), count = rsize;
        count; count--) {
      gcry_mpi_div(bndup, num, bndup, ten, 0);
      for (decnum = 0, count2 = gcry_mpi_get_nbits(num); count2;
          decnum *= 2, decnum += (gcry_mpi_test_bit(num, count2 - 1) ? 1 : 0),
          count2--)
        ;
      ret[count - 1] = decnum + '0';
    }
    for (count = 0; count < rsize && ret[count] == '0'; count++)
      ;
    for (count2 = 0; count2 < rsize - count; ++count2) {
      ret[count2] = ret[count2 + count];
    }
    ret[count2] = 0;
    bignum_free(num);
    bignum_free(bndup);
    bignum_free(ten);
  }

  return ret;
}
Ejemplo n.º 5
0
Archivo: bignum.c Proyecto: rtfb/82k
void bignum_free_base_convert_lut() {
    for (int i = 0; i < mul_lut_size; ++i) {
        bignum_free(&mul_lut[i]);
    }
    free(mul_lut);
    mul_lut = NULL;
    mul_lut_size = 0;
    for (int i = 0; i < SUMSZ; ++i) {
        for (int j = 0; j < 256; ++j) {
            bignum_free(&sum_lut[i][j]);
        }
    }
}
Ejemplo n.º 6
0
void ssh_crypto_finalize(void) {
  if (ssh_crypto_initialized) {
    bignum_free(g);
    g = NULL;
    bignum_free(p);
    p = NULL;
#ifdef HAVE_LIBGCRYPT
    gcry_control(GCRYCTL_TERM_SECMEM);
#elif defined HAVE_LIBCRYPTO
    EVP_cleanup();
    CRYPTO_cleanup_all_ex_data();
#endif	
    ssh_crypto_initialized=0;
  }
}
Ejemplo n.º 7
0
static int base58_decode(mrb_state *mrb, char *dst, const char *data, int length, const char *chars)
{
  int leading_zero = 0;
  int i;
  Bignum *result = bignum_alloc_char(mrb, 0);
  Bignum *base = bignum_alloc_char(mrb, 1);
  int b_length;

  for (i = 0; i < length; ++i) {
    if (data[i] == chars[0]) {
      leading_zero++;
    }
    else {
      break;
    }
  }
  
  memset(dst, 0, leading_zero);
  
  for (i = length - 1; i > leading_zero - 1; --i) {
    
    Bignum *f = bignum_alloc_char(mrb, 0);
    int j, c = -1;
    
    for (j = 0; j < 58; ++j) {
      if (data[i] == chars[j]) {
        c = j;
        break;
      }
    }
    
    if (c == -1) return -1;
    
    for (j = 0; j < c; ++j) bignum_add(result, base);
    for (j = 0; j < 58; ++j) bignum_add(f, base);
    
    bignum_free(base);
    base = f;
  }
  
  bignum_free(base);
  
  b_length = bignum_length(result);
  memcpy(dst + leading_zero, result->data + result->len - b_length , b_length);
  bignum_free(result);
  
  return leading_zero + b_length;
}
Ejemplo n.º 8
0
Archivo: bignum.c Proyecto: rtfb/82k
// a %= b
void bignum_mod(bignum *a, bignum *b) {
    bignum tmp;
    bignum_init(&tmp);
    bignum_div_mod(a, b, &tmp);
    bignum_copy(a, &tmp);
    bignum_free(&tmp);
}
Ejemplo n.º 9
0
Archivo: bignum.c Proyecto: rtfb/82k
// a *= b
void bignum_mul_int(bignum *a, unsigned int b) {
    bignum tmp;
    bignum_init(&tmp);
    uint8_t b_bytes[] = {
         b & 0x000000ff,
        (b & 0x0000ff00) >> 8,
        (b & 0x00ff0000) >> 16,
        (b & 0xff000000) >> 24,
    };
    int b_size = 3;
    while (b_size > 1 && b_bytes[b_size] == 0) --b_size;
    for (int bi = 0; bi < b_size; ++bi) {
        int carry = 0;
        for (int ai = 0; ai < a->size; ++ai) {
            int prod = carry + a->data[ai] * b_bytes[bi];
            carry = prod / 256;
            tmp.data[ai + bi] = prod % 256;
        }
        tmp.data[bi + a->size] = carry;
    }
    tmp.size = a->size + b_size;
    while (tmp.size > 0 && tmp.data[tmp.size - 1] == 0) {
        --tmp.size;
    }
    if (tmp.size == 0) {
        tmp.size = 1;
    }
    bignum_copy(a, &tmp);
    bignum_free(&tmp);
}
Ejemplo n.º 10
0
Archivo: bignum.c Proyecto: rtfb/82k
// a *= b
void bignum_mul_int_silly_loop(bignum *a, unsigned int b) {
    bignum tmp;
    bignum_init(&tmp);
    bignum_copy(&tmp, a);
    --b;
    // XXX: this loop is probably quite inefficient, think of something better
    while (b > 0) {
        bignum_add(a, &tmp);
        --b;
    }
    bignum_free(&tmp);
}
Ejemplo n.º 11
0
void crypto_free(CRYPTO *crypto){
  if (crypto == NULL) {
    return;
  }

  SAFE_FREE(crypto->server_pubkey);

  cipher_free(crypto->in_cipher);
  cipher_free(crypto->out_cipher);

  bignum_free(crypto->e);
  bignum_free(crypto->f);
  bignum_free(crypto->x);
  bignum_free(crypto->y);
  bignum_free(crypto->k);
  /* lot of other things */
  /* i'm lost in my own code. good work */
  memset(crypto,0,sizeof(*crypto));

  SAFE_FREE(crypto);
}
Ejemplo n.º 12
0
Archivo: dh.c Proyecto: mwgoldsmith/ssh
/*
 * This inits the values g and p which are used for DH key agreement
 * FIXME: Make the function thread safe by adding a semaphore or mutex.
 */
int ssh_crypto_init(void) {
  if (ssh_crypto_initialized == 0) {
#ifdef HAVE_LIBGCRYPT
    gcry_check_version(NULL);
    if (!gcry_control(GCRYCTL_INITIALIZATION_FINISHED_P,0)) {
      gcry_control(GCRYCTL_INIT_SECMEM, 4096);
      gcry_control(GCRYCTL_INITIALIZATION_FINISHED,0);
    }
#endif

    g = bignum_new();
    if (g == NULL) {
      return -1;
    }
    bignum_set_word(g,g_int);

#ifdef HAVE_LIBGCRYPT
    bignum_bin2bn(p_group1_value, P_GROUP1_LEN, &p_group1);
    if (p_group1 == NULL) {
      bignum_free(g);
      g = NULL;
      return -1;
    }
    bignum_bin2bn(p_group14_value, P_GROUP14_LEN, &p_group14);
    if (p_group14 == NULL) {
      bignum_free(g);
      bignum_free(p_group1);
      g = NULL;
      p_group1 = NULL;
      return -1;
    }

#elif defined HAVE_LIBCRYPTO
    p_group1 = bignum_new();
    if (p_group1 == NULL) {
      bignum_free(g);
      g = NULL;
      return -1;
    }
    bignum_bin2bn(p_group1_value, P_GROUP1_LEN, p_group1);

    p_group14 = bignum_new();
    if (p_group14 == NULL) {
      bignum_free(g);
      bignum_free(p_group1);
      g = NULL;
      p_group1 = NULL;
      return -1;
    }
    bignum_bin2bn(p_group14_value, P_GROUP14_LEN, p_group14);

    OpenSSL_add_all_algorithms();

#endif

    ssh_crypto_initialized = 1;
  }

  return 0;
}
Ejemplo n.º 13
0
Archivo: bignum.c Proyecto: rtfb/82k
/*
Examples:
82000 (base 3) = 11011111001 =
1*3**0 + 0*3**1 + 0*3**2 + 1*3**3 +3**4 +3**5 +3**6 +3**7 +0*3**8 +3**9 +3**10

82000 (base 5) = 10111000 =
0*5**0 + 0*5**1 + 0*5**2 + 1*5**3 + 1*5**4 + 1*5**5 + 0*5**6 + 1*5**7
*/
void bignum_from_string_binary(bignum *n, char const* s, size_t base) {
    char const *end_of_s = s + strlen(s) - 1;
    bignum_from_int(n, 0);
    bignum multiplier;
    bignum_init(&multiplier);
    bignum_from_int(&multiplier, 1);
    while (end_of_s != s) {
        assert((*end_of_s == '1') || (*end_of_s == '0'));
        if (*end_of_s == '1') {
            bignum_add(n, &multiplier);
        }
        bignum_mul_int(&multiplier, base);
        --end_of_s;
    }
    bignum_add(n, &multiplier);
    bignum_free(&multiplier);
}
Ejemplo n.º 14
0
static int base58_encode_reverse(mrb_state *mrb, char *dst, const char *data, int length, const char *chars)
{
  Bignum *b = bignum_alloc(mrb, data, length);
  int index = 0;
  int i;
  
  do {
    dst[index] = chars[bignum_div(b, 58)];
    index++;
  } while (!bignum_is_zero(b));
  
  for (i = 0; i < length; ++i) {
    if (data[i] == 0) {
      dst[index] = chars[0];
      index++;
    }
    else {
      break;
    }
  }
  bignum_free(b);
  return index;
}
Ejemplo n.º 15
0
void crypto_free(struct ssh_crypto_struct *crypto){
  int i;
  if (crypto == NULL) {
    return;
  }

  SAFE_FREE(crypto->server_pubkey);

  cipher_free(crypto->in_cipher);
  cipher_free(crypto->out_cipher);

  bignum_free(crypto->e);
  bignum_free(crypto->f);
  bignum_free(crypto->x);
  bignum_free(crypto->y);
  bignum_free(crypto->k);
#ifdef HAVE_ECDH
  SAFE_FREE(crypto->ecdh_client_pubkey);
  SAFE_FREE(crypto->ecdh_server_pubkey);
#endif
  if(crypto->session_id != NULL){
    memset(crypto->session_id, '\0', crypto->digest_len);
    SAFE_FREE(crypto->session_id);
  }

#ifdef WITH_ZLIB
  if (crypto->compress_out_ctx &&
      (deflateEnd(crypto->compress_out_ctx) != 0)) {
    inflateEnd(crypto->compress_out_ctx);
  }
  if (crypto->compress_in_ctx &&
      (deflateEnd(crypto->compress_in_ctx) != 0)) {
    inflateEnd(crypto->compress_in_ctx);
  }
#endif /* WITH_ZLIB */
  if(crypto->encryptIV)
    SAFE_FREE(crypto->encryptIV);
  if(crypto->decryptIV)
    SAFE_FREE(crypto->decryptIV);
  if(crypto->encryptMAC)
    SAFE_FREE(crypto->encryptMAC);
  if(crypto->decryptMAC)
    SAFE_FREE(crypto->decryptMAC);
  if(crypto->encryptkey){
    memset(crypto->encryptkey, 0, crypto->digest_len);
    SAFE_FREE(crypto->encryptkey);
  }
  if(crypto->decryptkey){
    memset(crypto->decryptkey, 0, crypto->digest_len);
    SAFE_FREE(crypto->decryptkey);
  }

  for (i = 0; i < SSH_KEX_METHODS; i++) {
      SAFE_FREE(crypto->client_kex.methods[i]);
      SAFE_FREE(crypto->server_kex.methods[i]);
      SAFE_FREE(crypto->kex_methods[i]);
  }

  memset(crypto,0,sizeof(*crypto));

  SAFE_FREE(crypto);
}
Ejemplo n.º 16
0
/**
 * @brief Write the current server as known in the known hosts file.
 *
 * This will create the known hosts file if it does not exist. You generaly use
 * it when ssh_is_server_known() answered SSH_SERVER_NOT_KNOWN.
 *
 * @param[in]  session  The ssh session to use.
 *
 * @return              SSH_OK on success, SSH_ERROR on error.
 */
int ssh_write_knownhost(ssh_session session) {
  ssh_string pubkey;
  unsigned char *pubkey_64;
  char buffer[4096] = {0};
  FILE *file;
  char *dir;
  char *host;
  char *hostport;
  size_t len = 0;

  if (session->host == NULL) {
    ssh_set_error(session, SSH_FATAL,
        "Can't write host in known hosts if the hostname isn't known");
    return SSH_ERROR;
  }

  host = ssh_lowercase(session->host);
  /* If using a nonstandard port, save the host in the [host]:port format */
  if(session->port != 22){
    hostport = ssh_hostport(host,session->port);
    SAFE_FREE(host);
    host=hostport;
    hostport=NULL;
  }

  if (session->knownhosts == NULL) {
    if (ssh_options_apply(session) < 0) {
      ssh_set_error(session, SSH_FATAL, "Can't find a known_hosts file");
      return SSH_ERROR;
    }
  }

  if(session->current_crypto==NULL) {
  	ssh_set_error(session, SSH_FATAL, "No current crypto context");
  	return SSH_ERROR;
  }

  pubkey = session->current_crypto->server_pubkey;
  if(pubkey == NULL){
  	ssh_set_error(session, SSH_FATAL, "No public key present");
  	return SSH_ERROR;
  }

  /* Check if ~/.ssh exists and create it if not */
  dir = ssh_dirname(session->knownhosts);
  if (dir == NULL) {
    ssh_set_error(session, SSH_FATAL, "%s", strerror(errno));
    return -1;
  }
  if (! ssh_file_readaccess_ok(dir)) {
    if (ssh_mkdir(dir, 0700) < 0) {
      ssh_set_error(session, SSH_FATAL,
          "Cannot create %s directory.", dir);
      SAFE_FREE(dir);
      return -1;
    }
  }
  SAFE_FREE(dir);

  file = fopen(session->knownhosts, "a");
  if (file == NULL) {
    ssh_set_error(session, SSH_FATAL,
        "Couldn't open known_hosts file %s for appending: %s",
        session->knownhosts, strerror(errno));
    SAFE_FREE(host);
    return -1;
  }

  if (strcmp(session->current_crypto->server_pubkey_type, "ssh-rsa1") == 0) {
    /* openssh uses a different format for ssh-rsa1 keys.
       Be compatible --kv */
    ssh_public_key key;
    char *e_string = NULL;
    char *n_string = NULL;
    bignum e = NULL;
    bignum n = NULL;
    int rsa_size;
#ifdef HAVE_LIBGCRYPT
    gcry_sexp_t sexp;
#endif

    key = publickey_from_string(session, pubkey);
    if (key == NULL) {
      fclose(file);
      SAFE_FREE(host);
      return -1;
    }

#ifdef HAVE_LIBGCRYPT
    sexp = gcry_sexp_find_token(key->rsa_pub, "e", 0);
    if (sexp == NULL) {
      publickey_free(key);
      fclose(file);
      SAFE_FREE(host);
      return -1;
    }
    e = gcry_sexp_nth_mpi(sexp, 1, GCRYMPI_FMT_USG);
    gcry_sexp_release(sexp);
    if (e == NULL) {
      publickey_free(key);
      fclose(file);
      SAFE_FREE(host);
      return -1;
    }

    sexp = gcry_sexp_find_token(key->rsa_pub, "n", 0);
    if (sexp == NULL) {
      publickey_free(key);
      bignum_free(e);
      fclose(file);
      SAFE_FREE(host);
      return -1;
    }
    n = gcry_sexp_nth_mpi(sexp, 1, GCRYMPI_FMT_USG);
    gcry_sexp_release(sexp);
    if (n == NULL) {
      publickey_free(key);
      bignum_free(e);
      fclose(file);
      SAFE_FREE(host);
      return -1;
    }

    rsa_size = (gcry_pk_get_nbits(key->rsa_pub) + 7) / 8;
#elif defined HAVE_LIBCRYPTO
    e = key->rsa_pub->e;
    n = key->rsa_pub->n;
    rsa_size = RSA_size(key->rsa_pub);
#endif

    e_string = bignum_bn2dec(e);
    n_string = bignum_bn2dec(n);
    if (e_string == NULL || n_string == NULL) {
#ifdef HAVE_LIBGCRYPT
      bignum_free(e);
      bignum_free(n);
      SAFE_FREE(e_string);
      SAFE_FREE(n_string);
#elif defined HAVE_LIBCRYPTO
      OPENSSL_free(e_string);
      OPENSSL_free(n_string);
#endif
      publickey_free(key);
      fclose(file);
      SAFE_FREE(host);
      return -1;
    }

    snprintf(buffer, sizeof(buffer),
        "%s %d %s %s\n",
        host,
        rsa_size << 3,
        e_string,
        n_string);

#ifdef HAVE_LIBGCRYPT
    bignum_free(e);
    bignum_free(n);
    SAFE_FREE(e_string);
    SAFE_FREE(n_string);
#elif defined HAVE_LIBCRYPTO
    OPENSSL_free(e_string);
    OPENSSL_free(n_string);
#endif

    publickey_free(key);
  } else {
    pubkey_64 = bin_to_base64(pubkey->string, ssh_string_len(pubkey));
    if (pubkey_64 == NULL) {
      fclose(file);
      SAFE_FREE(host);
      return -1;
    }

    snprintf(buffer, sizeof(buffer),
        "%s %s %s\n",
        host,
        session->current_crypto->server_pubkey_type,
        pubkey_64);

    SAFE_FREE(pubkey_64);
  }
  SAFE_FREE(host);
  len = strlen(buffer);
  if (fwrite(buffer, len, 1, file) != 1 || ferror(file)) {
    fclose(file);
    return -1;
  }

  fclose(file);
  return 0;
}
Ejemplo n.º 17
0
/**
 * @brief Check the public key in the known host line matches the public key of
 * the currently connected server.
 *
 * @param[in] session   The SSH session to use.
 *
 * @param[in] tokens    A list of tokens in the known_hosts line.
 *
 * @returns             1 if the key matches, 0 if the key doesn't match and -1
 *                      on error.
 */
static int check_public_key(ssh_session session, char **tokens) {
  ssh_string pubkey = session->current_crypto->server_pubkey;
  ssh_buffer pubkey_buffer;
  char *pubkey_64;

  /* ok we found some public key in known hosts file. now un-base64it */
  if (alldigits(tokens[1])) {
    /* openssh rsa1 format */
    bignum tmpbn;
    ssh_string tmpstring;
    unsigned int len;
    int i;

    pubkey_buffer = ssh_buffer_new();
    if (pubkey_buffer == NULL) {
      return -1;
    }

    tmpstring = ssh_string_from_char("ssh-rsa1");
    if (tmpstring == NULL) {
      ssh_buffer_free(pubkey_buffer);
      return -1;
    }

    if (buffer_add_ssh_string(pubkey_buffer, tmpstring) < 0) {
      ssh_buffer_free(pubkey_buffer);
      ssh_string_free(tmpstring);
      return -1;
    }
    ssh_string_free(tmpstring);

    for (i = 2; i < 4; i++) { /* e, then n */
      tmpbn = NULL;
      bignum_dec2bn(tokens[i], &tmpbn);
      if (tmpbn == NULL) {
        ssh_buffer_free(pubkey_buffer);
        return -1;
      }
      /* for some reason, make_bignum_string does not work
         because of the padding which it does --kv */
      /* tmpstring = make_bignum_string(tmpbn); */
      /* do it manually instead */
      len = bignum_num_bytes(tmpbn);
      tmpstring = malloc(4 + len);
      if (tmpstring == NULL) {
        ssh_buffer_free(pubkey_buffer);
        bignum_free(tmpbn);
        return -1;
      }
      /* TODO: fix the hardcoding */
      tmpstring->size = htonl(len);
#ifdef HAVE_LIBGCRYPT
      bignum_bn2bin(tmpbn, len, tmpstring->string);
#elif defined HAVE_LIBCRYPTO
      bignum_bn2bin(tmpbn, tmpstring->string);
#endif
      bignum_free(tmpbn);
      if (buffer_add_ssh_string(pubkey_buffer, tmpstring) < 0) {
        ssh_buffer_free(pubkey_buffer);
        ssh_string_free(tmpstring);
        bignum_free(tmpbn);
        return -1;
      }
      ssh_string_free(tmpstring);
    }
  } else {
    /* ssh-dss or ssh-rsa */
    pubkey_64 = tokens[2];
    pubkey_buffer = base64_to_bin(pubkey_64);
  }

  if (pubkey_buffer == NULL) {
    ssh_set_error(session, SSH_FATAL,
        "Verifying that server is a known host: base64 error");
    return -1;
  }

  if (buffer_get_rest_len(pubkey_buffer) != ssh_string_len(pubkey)) {
    ssh_buffer_free(pubkey_buffer);
    return 0;
  }

  /* now test that they are identical */
  if (memcmp(buffer_get_rest(pubkey_buffer), pubkey->string,
        buffer_get_rest_len(pubkey_buffer)) != 0) {
    ssh_buffer_free(pubkey_buffer);
    return 0;
  }

  ssh_buffer_free(pubkey_buffer);
  return 1;
}