Esempio n. 1
0
int ssh_agent_get_ident_count(struct ssh_session_struct *session) {
  ssh_buffer request = NULL;
  ssh_buffer reply = NULL;
  unsigned int type = 0;
  unsigned int c1 = 0, c2 = 0;
  uint32_t buf = 0;

  switch (session->version) {
    case 1:
      c1 = SSH_AGENTC_REQUEST_RSA_IDENTITIES;
      c2 = SSH_AGENT_RSA_IDENTITIES_ANSWER;
      break;
    case 2:
      c1 = SSH2_AGENTC_REQUEST_IDENTITIES;
      c2 = SSH2_AGENT_IDENTITIES_ANSWER;
      break;
    default:
      return 0;
  }

  /* send message to the agent requesting the list of identities */
  request = ssh_buffer_new();
  if (buffer_add_u8(request, c1) < 0) {
    ssh_set_error(session, SSH_FATAL, "Not enough space");
    return -1;
  }

  reply = ssh_buffer_new();
  if (reply == NULL) {
    ssh_set_error(session, SSH_FATAL, "Not enough space");
    return -1;
  }

  if (agent_talk(session, request, reply) < 0) {
    ssh_buffer_free(request);
    return 0;
  }
  ssh_buffer_free(request);

  /* get message type and verify the answer */
  buffer_get_u8(reply, (uint8_t *) &type);
  SSH_LOG(session, SSH_LOG_WARN,
      "Answer type: %d, expected answer: %d",
      type, c2);
  if (agent_failed(type)) {
    return 0;
  } else if (type != c2) {
    ssh_set_error(session, SSH_FATAL,
        "Bad authentication reply message type: %d", type);
    return -1;
  }

  buffer_get_u32(reply, &buf);
  session->agent->count = agent_get_u32((uint8_t*)&buf);
  SSH_LOG(session, SSH_LOG_DEBUG, "Agent count: %d",
      session->agent->count);
  if (session->agent->count > 1024) {
    ssh_set_error(session, SSH_FATAL,
        "Too many identities in authentication reply: %d",
        session->agent->count);
    ssh_buffer_free(reply);
    return -1;
  }

  if (session->agent->ident) {
    buffer_reinit(session->agent->ident);
  }
  session->agent->ident = reply;

  return session->agent->count;
}
Esempio n. 2
0
ssh_string ssh_agent_sign_data(ssh_session session,
                               const ssh_key pubkey,
                               struct ssh_buffer_struct *data)
{
    ssh_buffer request;
    ssh_buffer reply;
    ssh_string key_blob;
    ssh_string sig_blob;
    int type = SSH2_AGENT_FAILURE;
    int flags = 0;
    uint32_t dlen;
    int rc;

    request = ssh_buffer_new();
    if (request == NULL) {
        return NULL;
    }

    /* create request */
    if (buffer_add_u8(request, SSH2_AGENTC_SIGN_REQUEST) < 0) {
        return NULL;
    }

    rc = ssh_pki_export_pubkey_blob(pubkey, &key_blob);
    if (rc < 0) {
        ssh_buffer_free(request);
        return NULL;
    }

    /* adds len + blob */
    rc = buffer_add_ssh_string(request, key_blob);
    ssh_string_free(key_blob);
    if (rc < 0) {
        ssh_buffer_free(request);
        return NULL;
    }

    /* Add data */
    dlen = buffer_get_rest_len(data);
    if (buffer_add_u32(request, htonl(dlen)) < 0) {
        ssh_buffer_free(request);
        return NULL;
    }
    if (buffer_add_data(request, buffer_get_rest(data), dlen) < 0) {
        ssh_buffer_free(request);
        return NULL;
    }

    if (buffer_add_u32(request, htonl(flags)) < 0) {
        ssh_buffer_free(request);
        return NULL;
    }

    reply = ssh_buffer_new();
    if (reply == NULL) {
        ssh_buffer_free(request);
        return NULL;
    }

    /* send the request */
    if (agent_talk(session, request, reply) < 0) {
        ssh_buffer_free(request);
        return NULL;
    }
    ssh_buffer_free(request);

    /* check if reply is valid */
    if (buffer_get_u8(reply, (uint8_t *) &type) != sizeof(uint8_t)) {
        ssh_buffer_free(reply);
        return NULL;
    }

    if (agent_failed(type)) {
        SSH_LOG(session, SSH_LOG_WARN, "Agent reports failure in signing the key");
        ssh_buffer_free(reply);
        return NULL;
    } else if (type != SSH2_AGENT_SIGN_RESPONSE) {
        ssh_set_error(session, SSH_FATAL, "Bad authentication response: %d", type);
        ssh_buffer_free(reply);
        return NULL;
    }

    sig_blob = buffer_get_ssh_string(reply);
    ssh_buffer_free(reply);

    return sig_blob;
}
Esempio n. 3
0
ssh_string agent_sign_data(struct ssh_session_struct *session,
    struct ssh_buffer_struct *data,
    struct ssh_public_key_struct *pubkey) {
  struct ssh_string_struct *blob = NULL;
  struct ssh_string_struct *sig = NULL;
  struct ssh_buffer_struct *request = NULL;
  struct ssh_buffer_struct *reply = NULL;
  int type = SSH2_AGENT_FAILURE;
  int flags = 0;
  uint32_t dlen = 0;

  /* create blob from the pubkey */
  blob = publickey_to_string(pubkey);

  request = buffer_new();
  if (request == NULL) {
    goto error;
  }

  /* create request */
  if (buffer_add_u8(request, SSH2_AGENTC_SIGN_REQUEST) < 0) {
    goto error;
  }

  /* adds len + blob */
  if (buffer_add_ssh_string(request, blob) < 0) {
    goto error;
  }

  /* Add data */
  dlen = buffer_get_len(data);
  if (buffer_add_u32(request, htonl(dlen)) < 0) {
    goto error;
  }
  if (buffer_add_data(request, buffer_get(data), dlen) < 0) {
    goto error;
  }

  if (buffer_add_u32(request, htonl(flags)) < 0) {
    goto error;
  }

  string_free(blob);

  reply = buffer_new();
  if (reply == NULL) {
    goto error;
  }

  /* send the request */
  if (agent_talk(session, request, reply) < 0) {
    buffer_free(request);
    return NULL;
  }
  buffer_free(request);

  /* check if reply is valid */
  if (buffer_get_u8(reply, (uint8_t *) &type) != sizeof(uint8_t)) {
    goto error;
  }
  if (agent_failed(type)) {
    ssh_log(session, SSH_LOG_RARE, "Agent reports failure in signing the key");
    buffer_free(reply);
    return NULL;
  } else if (type != SSH2_AGENT_SIGN_RESPONSE) {
    ssh_set_error(session, SSH_FATAL, "Bad authentication response: %d", type);
    buffer_free(reply);
    return NULL;
  }

  sig = buffer_get_ssh_string(reply);

  buffer_free(reply);

  return sig;
error:
  ssh_set_error(session, SSH_FATAL, "Not enough memory");
  string_free(blob);
  buffer_free(request);
  buffer_free(reply);

  return NULL;
}