Ejemplo n.º 1
0
Archivo: keys.c Proyecto: rofl0r/libssh
/*
 * This function concats in a buffer the values needed to do a signature
 * verification. */
ssh_buffer ssh_userauth_build_digest(ssh_session session, ssh_message msg, char *service) {
    /*
         The value of 'signature' is a signature by the corresponding private
       key over the following data, in the following order:

          string    session identifier
          byte      SSH_MSG_USERAUTH_REQUEST
          string    user name
          string    service name
          string    "publickey"
          boolean   TRUE
          string    public key algorithm name
          string    public key to be used for authentication
    */
    struct ssh_crypto_struct *crypto = session->current_crypto ? session->current_crypto :
                                           session->next_crypto;
    ssh_buffer buffer = NULL;
    ssh_string session_id = NULL;
    uint8_t type = SSH2_MSG_USERAUTH_REQUEST;
    ssh_string username = ssh_string_from_char(msg->auth_request.username);
    ssh_string servicename = ssh_string_from_char(service);
    ssh_string method = ssh_string_from_char("publickey");
    uint8_t has_sign = 1;
    ssh_string algo = ssh_string_from_char(msg->auth_request.public_key->type_c);
    ssh_string publickey = publickey_to_string(msg->auth_request.public_key);

    buffer = ssh_buffer_new();
    if (buffer == NULL) {
        goto error;
    }
    session_id = ssh_string_new(SHA_DIGEST_LEN);
    if (session_id == NULL) {
        ssh_buffer_free(buffer);
        buffer = NULL;
        goto error;
    }
    ssh_string_fill(session_id, crypto->session_id, SHA_DIGEST_LEN);

    if(buffer_add_ssh_string(buffer, session_id) < 0 ||
            buffer_add_u8(buffer, type) < 0 ||
            buffer_add_ssh_string(buffer, username) < 0 ||
            buffer_add_ssh_string(buffer, servicename) < 0 ||
            buffer_add_ssh_string(buffer, method) < 0 ||
            buffer_add_u8(buffer, has_sign) < 0 ||
            buffer_add_ssh_string(buffer, algo) < 0 ||
            buffer_add_ssh_string(buffer, publickey) < 0) {
        ssh_buffer_free(buffer);
        buffer = NULL;
        goto error;
    }

error:
    if(session_id) ssh_string_free(session_id);
    if(username) ssh_string_free(username);
    if(servicename) ssh_string_free(servicename);
    if(method) ssh_string_free(method);
    if(algo) ssh_string_free(algo);
    if(publickey) ssh_string_free(publickey);
    return buffer;
}
Ejemplo n.º 2
0
static int ssh_gssapi_send_auth_mic(ssh_session session, ssh_string *oid_set, int n_oid){
    ssh_string str;
    int rc;
    int i;
    rc = buffer_add_u8(session->out_buffer, SSH2_MSG_USERAUTH_REQUEST);
    if (rc < 0) {
        goto fail;
    }
    /* username */
    str = ssh_string_from_char(session->opts.username);
    if (str == NULL) {
        goto fail;
    }
    rc = buffer_add_ssh_string(session->out_buffer, str);
    ssh_string_free(str);
    if (rc < 0) {
        goto fail;
    }
    /* service */
    str = ssh_string_from_char("ssh-connection");
    if (str == NULL) {
        goto fail;
    }
    rc = buffer_add_ssh_string(session->out_buffer, str);
    ssh_string_free(str);
    if (rc < 0) {
        goto fail;
    }
    /* method */
    str = ssh_string_from_char("gssapi-with-mic");
    if (str == NULL) {
        goto fail;
    }
    rc = buffer_add_ssh_string(session->out_buffer, str);
    ssh_string_free(str);
    if (rc < 0) {
        goto fail;
    }

    rc = buffer_add_u32(session->out_buffer, htonl(n_oid));
    if (rc < 0) {
        goto fail;
    }

    for (i=0; i<n_oid; ++i){
        rc = buffer_add_ssh_string(session->out_buffer, oid_set[i]);
        if (rc < 0) {
            goto fail;
        }
    }

    session->auth_state = SSH_AUTH_STATE_GSSAPI_REQUEST_SENT;
    return packet_send(session);
fail:
    buffer_reinit(session->out_buffer);
    return SSH_ERROR;
}
Ejemplo n.º 3
0
int sftp_reply_status(sftp_client_message msg, uint32_t status,
    const char *message) {
  ssh_buffer out;
  ssh_string s;

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

  s = ssh_string_from_char(message ? message : "");
  if (s == NULL) {
    ssh_buffer_free(out);
    return -1;
  }

  if (ssh_buffer_add_u32(out, msg->id) < 0 ||
      ssh_buffer_add_u32(out, htonl(status)) < 0 ||
      ssh_buffer_add_ssh_string(out, s) < 0 ||
      ssh_buffer_add_u32(out, 0) < 0 || /* language string */
      sftp_packet_write(msg->sftp, SSH_FXP_STATUS, out) < 0) {
    ssh_buffer_free(out);
    ssh_string_free(s);
    return -1;
  }

  ssh_buffer_free(out);
  ssh_string_free(s);

  return 0;
}
Ejemplo n.º 4
0
int ssh_send_keepalive(ssh_session session)
{
	/* TODO check the reply and all that */
	struct ssh_string_struct *req;
	int reply = 1;
	int rc = SSH_ERROR;

	enter_function();
	req = ssh_string_from_char("*****@*****.**");
	if (req == NULL) {
		ssh_set_error_oom(session);
		goto out;
	}

	if (buffer_add_u8(session->out_buffer, SSH2_MSG_GLOBAL_REQUEST) < 0 ||
	    buffer_add_ssh_string(session->out_buffer, req) < 0 ||
	    buffer_add_u8(session->out_buffer, reply == 0 ? 0 : 1) < 0) {
		ssh_set_error_oom(session);
		goto out;
	}

	if (packet_send(session) == SSH_ERROR)
		goto out;

	ssh_handle_packets(session, 0);

	ssh_log(session, SSH_LOG_PACKET, "Sent a keepalive");
	rc = SSH_OK;

out:
	ssh_string_free(req);
	leave_function();
	return rc;
}
Ejemplo n.º 5
0
int ssh_message_service_reply_success(ssh_message msg) {
  struct ssh_string_struct *service;
  ssh_session session;

  if (msg == NULL) {
    return SSH_ERROR;
  }
  session = msg->session;

  SSH_LOG(SSH_LOG_PACKET,
      "Sending a SERVICE_ACCEPT for service %s", msg->service_request.service);
  if (buffer_add_u8(session->out_buffer, SSH2_MSG_SERVICE_ACCEPT) < 0) {
    return -1;
  }
  service=ssh_string_from_char(msg->service_request.service);
  if (service == NULL) {
      return -1;
  }

  if (buffer_add_ssh_string(session->out_buffer, service) < 0) {
    ssh_string_free(service);
    return -1;
  }
  ssh_string_free(service);
  return packet_send(msg->session);
}
Ejemplo n.º 6
0
int channel_request_exec1(ssh_channel channel, const char *cmd) {
  ssh_session session;
  ssh_string command = NULL;

  if (channel == NULL) {
    return -1;
  }
  session = channel->session;

  command = ssh_string_from_char(cmd);
  if (command == NULL) {
    return -1;
  }

  if (buffer_add_u8(session->out_buffer, SSH_CMSG_EXEC_CMD) < 0 ||
      buffer_add_ssh_string(session->out_buffer, command) < 0) {
    ssh_string_free(command);
    return -1;
  }
  ssh_string_free(command);

  if(packet_send(session) == SSH_ERROR) {
    return -1;
  }

  ssh_log(session, SSH_LOG_RARE, "Executing %s ...", cmd);

  return 0;
}
Ejemplo n.º 7
0
/* this is a public key in openssh's format */
static ssh_string make_rsa1_string(ssh_string e, ssh_string n){
  ssh_buffer buffer = NULL;
  ssh_string rsa = NULL;
  ssh_string ret = NULL;

  buffer = ssh_buffer_new();
  rsa = ssh_string_from_char("ssh-rsa1");
  if (rsa == NULL) {
      goto error;
  }

  if (ssh_buffer_add_ssh_string(buffer, rsa) < 0) {
    goto error;
  }
  if (ssh_buffer_add_ssh_string(buffer, e) < 0) {
    goto error;
  }
  if (ssh_buffer_add_ssh_string(buffer, n) < 0) {
    goto error;
  }

  ret = ssh_string_new(ssh_buffer_get_len(buffer));
  if (ret == NULL) {
    goto error;
  }

  ssh_string_fill(ret, ssh_buffer_get(buffer), ssh_buffer_get_len(buffer));
error:
  ssh_buffer_free(buffer);
  ssh_string_free(rsa);

  return ret;
}
Ejemplo n.º 8
0
static int ssh_message_auth_reply_default(ssh_message msg,int partial) {
  ssh_session session = msg->session;
  char methods_c[128] = {0};
  ssh_string methods = NULL;
  int rc = SSH_ERROR;

  enter_function();

  if (buffer_add_u8(session->out_buffer, SSH2_MSG_USERAUTH_FAILURE) < 0) {
    return rc;
  }

  if (session->auth_methods == 0) {
    session->auth_methods = SSH_AUTH_METHOD_PUBLICKEY | SSH_AUTH_METHOD_PASSWORD;
  }
  if (session->auth_methods & SSH_AUTH_METHOD_PUBLICKEY) {
    strcat(methods_c, "publickey,");
  }
  if (session->auth_methods & SSH_AUTH_METHOD_INTERACTIVE) {
    strcat(methods_c, "keyboard-interactive,");
  }
  if (session->auth_methods & SSH_AUTH_METHOD_PASSWORD) {
    strcat(methods_c, "password,");
  }
  if (session->auth_methods & SSH_AUTH_METHOD_HOSTBASED) {
    strcat(methods_c, "hostbased,");
  }

  /* Strip the comma. */
  methods_c[strlen(methods_c) - 1] = '\0'; // strip the comma. We are sure there is at

  ssh_log(session, SSH_LOG_PACKET,
      "Sending a auth failure. methods that can continue: %s", methods_c);

  methods = ssh_string_from_char(methods_c);
  if (methods == NULL) {
    goto error;
  }

  if (buffer_add_ssh_string(msg->session->out_buffer, methods) < 0) {
    goto error;
  }

  if (partial) {
    if (buffer_add_u8(session->out_buffer, 1) < 0) {
      goto error;
    }
  } else {
    if (buffer_add_u8(session->out_buffer, 0) < 0) {
      goto error;
    }
  }

  rc = packet_send(msg->session);
error:
  ssh_string_free(methods);

  leave_function();
  return rc;
}
Ejemplo n.º 9
0
int sftp_reply_name(sftp_client_message msg, const char *name,
    sftp_attributes attr) {
  ssh_buffer out;
  ssh_string file;

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

  file = ssh_string_from_char(name);
  if (file == NULL) {
    ssh_buffer_free(out);
    return -1;
  }

  if (ssh_buffer_add_u32(out, msg->id) < 0 ||
      ssh_buffer_add_u32(out, htonl(1)) < 0 ||
      ssh_buffer_add_ssh_string(out, file) < 0 ||
      ssh_buffer_add_ssh_string(out, file) < 0 || /* The protocol is broken here between 3 & 4 */
      buffer_add_attributes(out, attr) < 0 ||
      sftp_packet_write(msg->sftp, SSH_FXP_NAME, out) < 0) {
    ssh_buffer_free(out);
    ssh_string_free(file);
    return -1;
  }
  ssh_buffer_free(out);
  ssh_string_free(file);

  return 0;
}
Ejemplo n.º 10
0
/* this function only sends the predefined set of kex methods */
int ssh_send_kex(ssh_session session, int server_kex) {
  struct ssh_kex_struct *kex = (server_kex ? &session->next_crypto->server_kex :
      &session->next_crypto->client_kex);
  ssh_string str = NULL;
  int i;

  enter_function();

  if (buffer_add_u8(session->out_buffer, SSH2_MSG_KEXINIT) < 0) {
    goto error;
  }
  if (buffer_add_data(session->out_buffer, kex->cookie, 16) < 0) {
    goto error;
  }

  if (hashbufout_add_cookie(session) < 0) {
    goto error;
  }

  ssh_list_kex(session, kex);

  for (i = 0; i < KEX_METHODS_SIZE; i++) {
    str = ssh_string_from_char(kex->methods[i]);
    if (str == NULL) {
      goto error;
    }

    if (buffer_add_ssh_string(session->out_hashbuf, str) < 0) {
      goto error;
    }
    if (buffer_add_ssh_string(session->out_buffer, str) < 0) {
      goto error;
    }
    ssh_string_free(str);
  }

  if (buffer_add_u8(session->out_buffer, 0) < 0) {
    goto error;
  }
  if (buffer_add_u32(session->out_buffer, 0) < 0) {
    goto error;
  }

  if (packet_send(session) == SSH_ERROR) {
    leave_function();
    return -1;
  }

  leave_function();
  return 0;
error:
  buffer_reinit(session->out_buffer);
  buffer_reinit(session->out_hashbuf);
  ssh_string_free(str);

  leave_function();
  return -1;
}
Ejemplo n.º 11
0
Archivo: kex.c Proyecto: simonsj/libssh
/* this function only sends the predefined set of kex methods */
int ssh_send_kex(ssh_session session, int server_kex) {
  struct ssh_kex_struct *kex = (server_kex ? &session->next_crypto->server_kex :
      &session->next_crypto->client_kex);
  ssh_string str = NULL;
  int i;
  int rc;

  rc = ssh_buffer_pack(session->out_buffer,
                       "bP",
                       SSH2_MSG_KEXINIT,
                       16,
                       kex->cookie); /* cookie */
  if (rc != SSH_OK)
    goto error;
  if (ssh_hashbufout_add_cookie(session) < 0) {
    goto error;
  }

  ssh_list_kex(kex);

  for (i = 0; i < KEX_METHODS_SIZE; i++) {
    str = ssh_string_from_char(kex->methods[i]);
    if (str == NULL) {
      goto error;
    }

    if (ssh_buffer_add_ssh_string(session->out_hashbuf, str) < 0) {
      goto error;
    }
    if (ssh_buffer_add_ssh_string(session->out_buffer, str) < 0) {
      goto error;
    }
    ssh_string_free(str);
    str = NULL;
  }

  rc = ssh_buffer_pack(session->out_buffer,
                       "bd",
                       0,
                       0);
  if (rc != SSH_OK) {
    goto error;
  }

  if (ssh_packet_send(session) == SSH_ERROR) {
    return -1;
  }

  SSH_LOG(SSH_LOG_PACKET, "SSH_MSG_KEXINIT sent");
  return 0;
error:
  ssh_buffer_reinit(session->out_buffer);
  ssh_buffer_reinit(session->out_hashbuf);
  ssh_string_free(str);

  return -1;
}
Ejemplo n.º 12
0
static void *thread_ssh_buffer_add_format(void *threadid)
{
    ssh_buffer buffer = NULL;
    uint8_t b;
    uint16_t w;
    uint32_t d;
    uint64_t q;
    ssh_string s = NULL;
    int rc;
    size_t len;
    uint8_t verif[] = "\x42\x13\x37\x0b\xad\xc0\xde\x13\x24\x35\x46"
        "\xac\xbd\xce\xdf"
        "\x00\x00\x00\x06" "libssh"
        "\x00\x00\x00\x05" "rocks"
        "So much"
        "Fun!";

    /* Unused */
    (void) threadid;

    /* Setup */
    buffer = ssh_buffer_new();
    if (buffer == NULL) {
        pthread_exit((void *)-1);
    }
    ssh_buffer_set_secure(buffer);

    b = 0x42;
    w = 0x1337;
    d = 0xbadc0de;
    q = 0x13243546acbdcedf;
    s = ssh_string_from_char("libssh");
    rc = ssh_buffer_pack(buffer,
                         "bwdqSsPt",
                         b,
                         w,
                         d,
                         q,
                         s,
                         "rocks",
                         7,
                         "So much",
                         "Fun!");
    assert_int_equal(rc, SSH_OK);

    len = ssh_buffer_get_len(buffer);
    assert_int_equal(len, sizeof(verif) - 1);
    assert_memory_equal(ssh_buffer_get(buffer), verif, sizeof(verif) -1);

    SSH_STRING_FREE(s);

    /* Teardown */
    SSH_BUFFER_FREE(buffer);
    pthread_exit(NULL);
}
Ejemplo n.º 13
0
Archivo: pki.c Proyecto: codinn/libssh
int ssh_pki_export_signature_blob(const ssh_signature sig,
                                  ssh_string *sig_blob)
{
    ssh_buffer buf = NULL;
    ssh_string str;
    int rc;

    if (sig == NULL || sig_blob == NULL) {
        return SSH_ERROR;
    }

    buf = ssh_buffer_new();
    if (buf == NULL) {
        return SSH_ERROR;
    }

    str = ssh_string_from_char(sig->type_c);
    if (str == NULL) {
        ssh_buffer_free(buf);
        return SSH_ERROR;
    }

    rc = ssh_buffer_add_ssh_string(buf, str);
    ssh_string_free(str);
    if (rc < 0) {
        ssh_buffer_free(buf);
        return SSH_ERROR;
    }

    str = pki_signature_to_blob(sig);
    if (str == NULL) {
        ssh_buffer_free(buf);
        return SSH_ERROR;
    }

    rc = ssh_buffer_add_ssh_string(buf, str);
    ssh_string_free(str);
    if (rc < 0) {
        ssh_buffer_free(buf);
        return SSH_ERROR;
    }

    str = ssh_string_new(ssh_buffer_get_len(buf));
    if (str == NULL) {
        ssh_buffer_free(buf);
        return SSH_ERROR;
    }

    ssh_string_fill(str, ssh_buffer_get(buf), ssh_buffer_get_len(buf));
    ssh_buffer_free(buf);

    *sig_blob = str;

    return SSH_OK;
}
Ejemplo n.º 14
0
int ssh_message_auth_reply_pk_ok_simple(ssh_message msg) {
	ssh_string algo;
	ssh_string pubkey;
	int ret;
	algo=ssh_string_from_char(msg->auth_request.public_key->type_c);
	pubkey=publickey_to_string(msg->auth_request.public_key);
	ret=ssh_message_auth_reply_pk_ok(msg,algo,pubkey);
	ssh_string_free(algo);
	ssh_string_free(pubkey);
	return ret;
}
Ejemplo n.º 15
0
void server_handle_message(ssh_session s, ssh_message m, int type, int subtype, int *state)
{
    int handled = 0;
    if((*state == SERVER_CONNECTED) && (type == SSH_REQUEST_AUTH) && (subtype == SSH_AUTH_METHOD_PUBLICKEY))
    {
        ssh_public_key key = ssh_message_auth_publickey(m);
        ssh_string keystr = publickey_to_string(key);
        char *keyhash = pubkey_hash(keystr);
        int has_sig = ssh_message_auth_publickey_state(m);
        if(has_sig == SSH_PUBLICKEY_STATE_NONE)
        {
            if(authenticate(keyhash, 1))
            {
                //FIXME: type detection
                ssh_string algostr = ssh_string_from_char("ssh-rsa");
                ssh_message_auth_reply_pk_ok(m, algostr, keystr);
                handled = 1;
                ssh_string_free(algostr);
            }
        }
        else if(has_sig == SSH_PUBLICKEY_STATE_VALID)
        {
            if(authenticate(keyhash, 0))
            {
                session_event(s, "authenticated", keyhash);
                ssh_message_auth_reply_success(m, 0);
                handled = 1;
                *state = SERVER_AUTHENTICATED;
            }
            else
            {
                ssh_message_reply_default(m);
                handled = 1;
                *state = SERVER_CLOSED;
            }
        }
        ssh_string_free(keystr);
        free(keyhash);
    }
    else if((*state == SERVER_AUTHENTICATED) && (type == SSH_REQUEST_CHANNEL_OPEN) && (subtype == SSH_CHANNEL_SESSION))
    {
        ssh_channel chan = ssh_message_channel_request_open_reply_accept(m);
        if(!chan)
            session_error(s, "open-channel");
        handled = 1;
        session_event(s, "channel-opened", NULL);
        channel_to_file(chan, 1);
        ssh_channel_free(chan);
        *state = SERVER_CLOSED;
    }
    if(!handled)
        ssh_message_reply_default(m);
}
Ejemplo n.º 16
0
/**
 * @internal
 *
 * @brief Request a service from the SSH server.
 *
 * Service requests are for example: ssh-userauth, ssh-connection, etc.
 *
 * @param  session      The session to use to ask for a service request.
 * @param  service      The service request.
 *
 * @return SSH_OK on success
 * @return SSH_ERROR on error
 * @return SSH_AGAIN No response received yet
 * @bug actually only works with ssh-userauth
 */
int ssh_service_request(ssh_session session, const char *service) {
  ssh_string service_s = NULL;
  int rc=SSH_ERROR;

  if(session->auth_service_state != SSH_AUTH_SERVICE_NONE)
    goto pending;
  if (buffer_add_u8(session->out_buffer, SSH2_MSG_SERVICE_REQUEST) < 0) {
      return SSH_ERROR;
  }
  service_s = ssh_string_from_char(service);
  if (service_s == NULL) {
      return SSH_ERROR;
  }

  if (buffer_add_ssh_string(session->out_buffer,service_s) < 0) {
    ssh_string_free(service_s);
      return SSH_ERROR;
  }
  ssh_string_free(service_s);
  session->auth_service_state=SSH_AUTH_SERVICE_SENT;
  if (packet_send(session) == SSH_ERROR) {
    ssh_set_error(session, SSH_FATAL,
        "Sending SSH2_MSG_SERVICE_REQUEST failed.");
      return SSH_ERROR;
  }

  SSH_LOG(SSH_LOG_PACKET,
      "Sent SSH_MSG_SERVICE_REQUEST (service %s)", service);
pending:
  rc=ssh_handle_packets_termination(session,SSH_TIMEOUT_USER,
      ssh_service_request_termination, session);
  if (rc == SSH_ERROR) {
      return SSH_ERROR;
  }
  switch(session->auth_service_state){
  case SSH_AUTH_SERVICE_DENIED:
    ssh_set_error(session,SSH_FATAL,"ssh_auth_service request denied");
    break;
  case SSH_AUTH_SERVICE_ACCEPTED:
    rc=SSH_OK;
    break;
  case SSH_AUTH_SERVICE_SENT:
    rc=SSH_AGAIN;
    break;
  case SSH_AUTH_SERVICE_NONE:
  case SSH_AUTH_SERVICE_USER_SENT:
    /* Invalid state, SSH1 specific */
    rc=SSH_ERROR;
    break;
  }

  return rc;
}
Ejemplo n.º 17
0
Archivo: pki.c Proyecto: codinn/libssh
static int pki_import_cert_buffer(ssh_buffer buffer,
                                  enum ssh_keytypes_e type,
                                  ssh_key *pkey) {
    ssh_buffer cert;
    ssh_string type_s;
    ssh_key key;
    int rc;

    key = ssh_key_new();
    if (key == NULL) {
        return SSH_ERROR;
    }
    cert = ssh_buffer_new();
    if (cert == NULL) {
        ssh_key_free(key);
        return SSH_ERROR;
    }

    key->type = type;
    key->type_c = ssh_key_type_to_char(type);
    key->flags = SSH_KEY_FLAG_PUBLIC;

    /*
     * The cert blob starts with the key type as an ssh_string, but this
     * string has been read out of the buffer to identify the key type.
     * Simply add it again as first element before copying the rest.
     */
    type_s = ssh_string_from_char(key->type_c);
    if (type_s == NULL) {
        goto fail;
    }
    rc = ssh_buffer_add_ssh_string(cert, type_s);
    ssh_string_free(type_s);
    if (rc != 0) {
        goto fail;
    }

    rc = ssh_buffer_add_buffer(cert, buffer);
    if (rc != 0) {
        goto fail;
    }
    key->cert = (void*) cert;

    *pkey = key;
    return SSH_OK;

fail:
    ssh_key_free(key);
    ssh_buffer_free(cert);
    return SSH_ERROR;
}
Ejemplo n.º 18
0
static int send_username(ssh_session session, const char *username) {
  ssh_string user = NULL;
  /* returns SSH_AUTH_SUCCESS or SSH_AUTH_DENIED */
  if(session->auth_service_state == SSH_AUTH_SERVICE_USER_SENT) {
    if(session->auth_state == SSH_AUTH_STATE_FAILED)
      return SSH_AUTH_DENIED;
    if(session->auth_state == SSH_AUTH_STATE_SUCCESS)
      return SSH_AUTH_SUCCESS;
    return SSH_AUTH_ERROR;
  }

  if (!username) {
    if(!(username = session->username)) {
      if (ssh_options_set(session, SSH_OPTIONS_USER, NULL) < 0) {
        session->auth_service_state = SSH_AUTH_SERVICE_DENIED;
        return SSH_ERROR;
      } else {
        username = session->username;
      }
    }
  }
  user = ssh_string_from_char(username);
  if (user == NULL) {
    return SSH_AUTH_ERROR;
  }

  if (buffer_add_u8(session->out_buffer, SSH_CMSG_USER) < 0) {
    ssh_string_free(user);
    return SSH_AUTH_ERROR;
  }
  if (buffer_add_ssh_string(session->out_buffer, user) < 0) {
    ssh_string_free(user);
    return SSH_AUTH_ERROR;
  }
  ssh_string_free(user);
  session->auth_state=SSH_AUTH_STATE_NONE;
  if (packet_send(session) == SSH_ERROR) {
    return SSH_AUTH_ERROR;
  }

  if(wait_auth1_status(session) == SSH_AUTH_SUCCESS){
    session->auth_service_state=SSH_AUTH_SERVICE_USER_SENT;
    session->auth_state=SSH_AUTH_STATE_SUCCESS;
    return SSH_AUTH_SUCCESS;
  } else {
    session->auth_service_state=SSH_AUTH_SERVICE_USER_SENT;
    ssh_set_error(session,SSH_REQUEST_DENIED,"Password authentication necessary for user %s",username);
    return SSH_AUTH_DENIED;
  }

}
Ejemplo n.º 19
0
int sftp_reply_names_add(sftp_client_message msg, const char *file,
    const char *longname, sftp_attributes attr) {
  ssh_string name;

  name = ssh_string_from_char(file);
  if (name == NULL) {
    return -1;
  }

  if (msg->attrbuf == NULL) {
    msg->attrbuf = ssh_buffer_new();
    if (msg->attrbuf == NULL) {
      ssh_string_free(name);
      return -1;
    }
  }

  if (ssh_buffer_add_ssh_string(msg->attrbuf, name) < 0) {
    ssh_string_free(name);
    return -1;
  }

  ssh_string_free(name);
  name = ssh_string_from_char(longname);
  if (name == NULL) {
    return -1;
  }
  if (ssh_buffer_add_ssh_string(msg->attrbuf,name) < 0 ||
      buffer_add_attributes(msg->attrbuf,attr) < 0) {
    ssh_string_free(name);
    return -1;
  }
  ssh_string_free(name);
  msg->attr_num++;

  return 0;
}
Ejemplo n.º 20
0
/**
 * @internal
 *
 * @brief Request a service from the SSH server.
 *
 * Service requests are for example: ssh-userauth, ssh-connection, etc.
 *
 * @param  session      The session to use to ask for a service request.
 * @param  service      The service request.
 *
 * @return SSH_OK on success
 * @return SSH_ERROR on error
 * @return SSH_AGAIN No response received yet
 * @bug actually only works with ssh-userauth
 */
int ssh_service_request(ssh_session session, const char *service) {
  ssh_string service_s = NULL;
  int rc=SSH_ERROR;
  enter_function();
  switch(session->auth_service_state){
  	case SSH_AUTH_SERVICE_NONE:
  		if (buffer_add_u8(session->out_buffer, SSH2_MSG_SERVICE_REQUEST) < 0) {
  			break;
  		}
  		service_s = ssh_string_from_char(service);
  		if (service_s == NULL) {
  			break;
  		}

  		if (buffer_add_ssh_string(session->out_buffer,service_s) < 0) {
  			ssh_string_free(service_s);
  			break;
  		}
  		ssh_string_free(service_s);

  		if (packet_send(session) == SSH_ERROR) {
  			ssh_set_error(session, SSH_FATAL,
  					"Sending SSH2_MSG_SERVICE_REQUEST failed.");
  			break;
  		}

  		ssh_log(session, SSH_LOG_PACKET,
  				"Sent SSH_MSG_SERVICE_REQUEST (service %s)", service);
  		session->auth_service_state=SSH_AUTH_SERVICE_SENT;
  		rc=SSH_AGAIN;
  		break;
  	case SSH_AUTH_SERVICE_DENIED:
  		ssh_set_error(session,SSH_FATAL,"ssh_auth_service request denied");
  		break;
  	case SSH_AUTH_SERVICE_ACCEPTED:
  		rc=SSH_OK;
  		break;
  	case SSH_AUTH_SERVICE_SENT:
  		rc=SSH_AGAIN;
  		break;
  	case SSH_AUTH_SERVICE_USER_SENT:
  	  /* Invalid state, SSH1 specific */
  	  rc=SSH_ERROR;
  	  break;
  }

  leave_function();
  return rc;
}
Ejemplo n.º 21
0
Archivo: keys.c Proyecto: rofl0r/libssh
/**
 * @brief Convert a public_key object into a a SSH string.
 *
 * @param[in]  key      The public key to convert.
 *
 * @returns             An allocated SSH String containing the public key, NULL
 *                      on error.
 *
 * @see string_free()
 */
ssh_string publickey_to_string(ssh_public_key key) {
    ssh_string type = NULL;
    ssh_string ret = NULL;
    ssh_buffer buf = NULL;

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

    type = ssh_string_from_char(key->type_c);
    if (type == NULL) {
        goto error;
    }

    if (buffer_add_ssh_string(buf, type) < 0) {
        goto error;
    }

    switch (key->type) {
    case SSH_KEYTYPE_DSS:
        if (dsa_public_to_string(key->dsa_pub, buf) < 0) {
            goto error;
        }
        break;
    case SSH_KEYTYPE_RSA:
    case SSH_KEYTYPE_RSA1:
        if (rsa_public_to_string(key->rsa_pub, buf) < 0) {
            goto error;
        }
        break;
    }

    ret = ssh_string_new(buffer_get_rest_len(buf));
    if (ret == NULL) {
        goto error;
    }

    ssh_string_fill(ret, buffer_get_rest(buf), buffer_get_rest_len(buf));
error:
    ssh_buffer_free(buf);
    if(type != NULL)
        ssh_string_free(type);

    return ret;
}
Ejemplo n.º 22
0
int ssh_send_keepalive(ssh_session session)
{
  struct ssh_string_struct *req;
  int rc;

  rc = buffer_add_u8(session->out_buffer, SSH2_MSG_GLOBAL_REQUEST);
  if (rc < 0) {
    goto err;
  }

  req = ssh_string_from_char("*****@*****.**");
  if (req == NULL) {
    goto err;
  }

  rc = buffer_add_ssh_string(session->out_buffer, req);
  ssh_string_free(req);
  if (rc < 0) {
    goto err;
  }

  rc = buffer_add_u8(session->out_buffer, 1);
  if (rc < 0) {
    goto err;
  }

  if (packet_send(session) == SSH_ERROR) {
    goto err;
  }

  ssh_handle_packets(session, 0);

  SSH_LOG(SSH_LOG_PACKET, "Sent a keepalive");
  return SSH_OK;

err:
  ssh_set_error_oom(session);
  ssh_buffer_reinit(session->out_buffer);
  return SSH_ERROR;
}
Ejemplo n.º 23
0
int ssh_message_auth_reply_pk_ok_simple(ssh_message msg) {
    ssh_string algo;
    ssh_string pubkey_blob = NULL;
    int ret;

    algo = ssh_string_from_char(msg->auth_request.pubkey->type_c);
    if (algo == NULL) {
        return SSH_ERROR;
    }

    ret = ssh_pki_export_pubkey_blob(msg->auth_request.pubkey, &pubkey_blob);
    if (ret < 0) {
        ssh_string_free(algo);
        return SSH_ERROR;
    }

    ret = ssh_message_auth_reply_pk_ok(msg, algo, pubkey_blob);

    ssh_string_free(algo);
    ssh_string_free(pubkey_blob);

    return ret;
}
Ejemplo n.º 24
0
Archivo: keys.c Proyecto: rofl0r/libssh
/* Signature decoding functions */
ssh_string signature_to_string(SIGNATURE *sign) {
    unsigned char buffer[40] = {0};
    ssh_buffer tmpbuf = NULL;
    ssh_string str = NULL;
    ssh_string tmp = NULL;
    ssh_string rs = NULL;
    int rc = -1;
#ifdef HAVE_LIBGCRYPT
    const char *r = NULL;
    const char *s = NULL;
    gcry_sexp_t sexp;
    size_t size = 0;
#elif defined HAVE_LIBCRYPTO
    ssh_string r = NULL;
    ssh_string s = NULL;
#endif

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

    tmp = ssh_string_from_char(ssh_type_to_char(sign->type));
    if (tmp == NULL) {
        ssh_buffer_free(tmpbuf);
        return NULL;
    }
    if (buffer_add_ssh_string(tmpbuf, tmp) < 0) {
        ssh_buffer_free(tmpbuf);
        ssh_string_free(tmp);
        return NULL;
    }
    ssh_string_free(tmp);

    switch(sign->type) {
    case SSH_KEYTYPE_DSS:
#ifdef HAVE_LIBGCRYPT
        sexp = gcry_sexp_find_token(sign->dsa_sign, "r", 0);
        if (sexp == NULL) {
            ssh_buffer_free(tmpbuf);
            return NULL;
        }
        r = gcry_sexp_nth_data(sexp, 1, &size);
        if (*r == 0) {      /* libgcrypt put 0 when first bit is set */
            size--;
            r++;
        }
        memcpy(buffer, r + size - 20, 20);
        gcry_sexp_release(sexp);

        sexp = gcry_sexp_find_token(sign->dsa_sign, "s", 0);
        if (sexp == NULL) {
            ssh_buffer_free(tmpbuf);
            return NULL;
        }
        s = gcry_sexp_nth_data(sexp,1,&size);
        if (*s == 0) {
            size--;
            s++;
        }
        memcpy(buffer+ 20, s + size - 20, 20);
        gcry_sexp_release(sexp);
#elif defined HAVE_LIBCRYPTO
        r = make_bignum_string(sign->dsa_sign->r);
        if (r == NULL) {
            ssh_buffer_free(tmpbuf);
            return NULL;
        }
        s = make_bignum_string(sign->dsa_sign->s);
        if (s == NULL) {
            ssh_buffer_free(tmpbuf);
            ssh_string_free(r);
            return NULL;
        }

        memcpy(buffer, (char *)ssh_string_data(r) + ssh_string_len(r) - 20, 20);
        memcpy(buffer + 20, (char *)ssh_string_data(s) + ssh_string_len(s) - 20, 20);

        ssh_string_free(r);
        ssh_string_free(s);
#endif /* HAVE_LIBCRYPTO */
        rs = ssh_string_new(40);
        if (rs == NULL) {
            ssh_buffer_free(tmpbuf);
            return NULL;
        }

        ssh_string_fill(rs, buffer, 40);
        rc = buffer_add_ssh_string(tmpbuf, rs);
        ssh_string_free(rs);
        if (rc < 0) {
            ssh_buffer_free(tmpbuf);
            return NULL;
        }

        break;
    case SSH_KEYTYPE_RSA:
    case SSH_KEYTYPE_RSA1:
#ifdef HAVE_LIBGCRYPT
        sexp = gcry_sexp_find_token(sign->rsa_sign, "s", 0);
        if (sexp == NULL) {
            ssh_buffer_free(tmpbuf);
            return NULL;
        }
        s = gcry_sexp_nth_data(sexp,1,&size);
        if (*s == 0) {
            size--;
            s++;
        }
        rs = ssh_string_new(size);
        if (rs == NULL) {
            ssh_buffer_free(tmpbuf);
            return NULL;
        }

        ssh_string_fill(rs, (char *) s, size);
        rc = buffer_add_ssh_string(tmpbuf, rs);
        gcry_sexp_release(sexp);
        ssh_string_free(rs);
        if (rc < 0) {
            ssh_buffer_free(tmpbuf);
            return NULL;
        }
#elif defined HAVE_LIBCRYPTO
        if (buffer_add_ssh_string(tmpbuf,sign->rsa_sign) < 0) {
            ssh_buffer_free(tmpbuf);
            return NULL;
        }
#endif
        break;
    }

    str = ssh_string_new(buffer_get_rest_len(tmpbuf));
    if (str == NULL) {
        ssh_buffer_free(tmpbuf);
        return NULL;
    }
    ssh_string_fill(str, buffer_get_rest(tmpbuf), buffer_get_rest_len(tmpbuf));
    ssh_buffer_free(tmpbuf);

    return str;
}
Ejemplo n.º 25
0
int ssh_userauth1_password(ssh_session session, const char *username,
    const char *password) {
  ssh_string pwd = NULL;
  int rc;
  enter_function();
  rc = send_username(session, username);
  if (rc != SSH_AUTH_DENIED) {
    leave_function();
    return rc;
  }

  /* we trick a bit here. A known flaw in SSH1 protocol is that it's
   * easy to guess password sizes.
   * not that sure ...
   */

  /* XXX fix me here ! */
  /* cisco IOS doesn't like when a password is followed by zeroes and random pad. */
  if(1 || strlen(password) >= 128) {
    /* not risky to disclose the size of such a big password .. */
    pwd = ssh_string_from_char(password);
    if (pwd == NULL) {
      leave_function();
      return SSH_AUTH_ERROR;
    }
  } else {
    /* fill the password string from random things. the strcpy
     * ensure there is at least a nul byte after the password.
     * most implementation won't see the garbage at end.
     * why garbage ? because nul bytes will be compressed by
     * gzip and disclose password len.
     */
    pwd = ssh_string_new(128);
    if (pwd == NULL) {
      leave_function();
      return SSH_AUTH_ERROR;
    }
    ssh_get_random( pwd->string, 128, 0);
    strcpy((char *) pwd->string, password);
  }

  if (buffer_add_u8(session->out_buffer, SSH_CMSG_AUTH_PASSWORD) < 0) {
    ssh_string_burn(pwd);
    ssh_string_free(pwd);
    leave_function();
    return SSH_AUTH_ERROR;
  }
  if (buffer_add_ssh_string(session->out_buffer, pwd) < 0) {
    ssh_string_burn(pwd);
    ssh_string_free(pwd);
    leave_function();
    return SSH_AUTH_ERROR;
  }

  ssh_string_burn(pwd);
  ssh_string_free(pwd);
  session->auth_state=SSH_AUTH_STATE_NONE;
  if (packet_send(session) == SSH_ERROR) {
    leave_function();
    return SSH_AUTH_ERROR;
  }
  rc = wait_auth1_status(session);
  leave_function();
  return rc;
}
Ejemplo n.º 26
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;
}
Ejemplo n.º 27
0
/**
 * @brief Disconnect from a session (client or server).
 * The session can then be reused to open a new session.
 *
 * @param[in]  session  The SSH session to use.
 */
void ssh_disconnect(ssh_session session) {
  ssh_string str = NULL;
  struct ssh_iterator *it;

  if (session == NULL) {
    return;
  }

  if (session->socket != NULL && ssh_socket_is_open(session->socket)) {
    if (buffer_add_u8(session->out_buffer, SSH2_MSG_DISCONNECT) < 0) {
      goto error;
    }
    if (buffer_add_u32(session->out_buffer,
          htonl(SSH2_DISCONNECT_BY_APPLICATION)) < 0) {
      goto error;
    }

    str = ssh_string_from_char("Bye Bye");
    if (str == NULL) {
      goto error;
    }

    if (buffer_add_ssh_string(session->out_buffer,str) < 0) {
      ssh_string_free(str);
      goto error;
    }
    ssh_string_free(str);

    packet_send(session);
    ssh_socket_close(session->socket);
  }
error:
  session->alive = 0;
  if (session->socket != NULL){
    ssh_socket_reset(session->socket);
  }
  session->opts.fd = SSH_INVALID_SOCKET;
  session->session_state=SSH_SESSION_STATE_DISCONNECTED;

  while ((it=ssh_list_get_iterator(session->channels)) != NULL) {
    ssh_channel_do_free(ssh_iterator_value(ssh_channel,it));
    ssh_list_remove(session->channels, it);
  }
  if(session->current_crypto){
    crypto_free(session->current_crypto);
    session->current_crypto=NULL;
  }
  if (session->in_buffer) {
    ssh_buffer_reinit(session->in_buffer);
  }
  if (session->out_buffer) {
    ssh_buffer_reinit(session->out_buffer);
  }
  if (session->in_hashbuf) {
    ssh_buffer_reinit(session->in_hashbuf);
  }
  if (session->out_hashbuf) {
    ssh_buffer_reinit(session->out_hashbuf);
  }
  session->auth_methods = 0;
  SAFE_FREE(session->serverbanner);
  SAFE_FREE(session->clientbanner);

  if(session->ssh_message_list){
    ssh_message msg;
    while((msg=ssh_list_pop_head(ssh_message ,session->ssh_message_list))
        != NULL){
      ssh_message_free(msg);
    }
    ssh_list_free(session->ssh_message_list);
    session->ssh_message_list=NULL;
  }

  if (session->packet_callbacks){
    ssh_list_free(session->packet_callbacks);
    session->packet_callbacks=NULL;
  }
}
Ejemplo n.º 28
0
/** @internal
 * replies to an SSH_AUTH packet with a default (denied) response.
 */
int ssh_auth_reply_default(ssh_session session,int partial) {
  char methods_c[128] = {0};
  ssh_string methods = NULL;
  int rc = SSH_ERROR;

  if (buffer_add_u8(session->out_buffer, SSH2_MSG_USERAUTH_FAILURE) < 0) {
    return rc;
  }

  if (session->auth_methods == 0) {
    session->auth_methods = SSH_AUTH_METHOD_PUBLICKEY | SSH_AUTH_METHOD_PASSWORD;
  }
  if (session->auth_methods & SSH_AUTH_METHOD_PUBLICKEY) {
    strncat(methods_c, "publickey,",
            sizeof(methods_c) - strlen(methods_c) - 1);
  }
  if (session->auth_methods & SSH_AUTH_METHOD_GSSAPI_MIC){
	  strncat(methods_c,"gssapi-with-mic,",
			  sizeof(methods_c) - strlen(methods_c) - 1);
  }
  if (session->auth_methods & SSH_AUTH_METHOD_INTERACTIVE) {
    strncat(methods_c, "keyboard-interactive,",
            sizeof(methods_c) - strlen(methods_c) - 1);
  }
  if (session->auth_methods & SSH_AUTH_METHOD_PASSWORD) {
    strncat(methods_c, "password,",
            sizeof(methods_c) - strlen(methods_c) - 1);
  }
  if (session->auth_methods & SSH_AUTH_METHOD_HOSTBASED) {
    strncat(methods_c, "hostbased,",
            sizeof(methods_c) - strlen(methods_c) - 1);
  }

  if (methods_c[0] == '\0' || methods_c[strlen(methods_c)-1] != ',') {
      return SSH_ERROR;
  }

  /* Strip the comma. */
  methods_c[strlen(methods_c) - 1] = '\0'; // strip the comma. We are sure there is at

  SSH_LOG(SSH_LOG_PACKET,
      "Sending a auth failure. methods that can continue: %s", methods_c);

  methods = ssh_string_from_char(methods_c);
  if (methods == NULL) {
    goto error;
  }

  if (buffer_add_ssh_string(session->out_buffer, methods) < 0) {
    goto error;
  }

  if (partial) {
    if (buffer_add_u8(session->out_buffer, 1) < 0) {
      goto error;
    }
  } else {
    if (buffer_add_u8(session->out_buffer, 0) < 0) {
      goto error;
    }
  }

  rc = packet_send(session);
error:
  ssh_string_free(methods);

  return rc;
}
Ejemplo n.º 29
0
int channel_request_pty_size1(ssh_channel channel, const char *terminal, int col,
    int row) {
  ssh_session session;
  ssh_string str = NULL;

  if (channel == NULL) {
    return SSH_ERROR;
  }
  session = channel->session;

  if(channel->request_state != SSH_CHANNEL_REQ_STATE_NONE){
    ssh_set_error(session,SSH_REQUEST_DENIED,"Wrong request state");
    return SSH_ERROR;
  }
  str = ssh_string_from_char(terminal);
  if (str == NULL) {
    ssh_set_error_oom(session);
    return -1;
  }

  if (buffer_add_u8(session->out_buffer, SSH_CMSG_REQUEST_PTY) < 0 ||
      buffer_add_ssh_string(session->out_buffer, str) < 0) {
    ssh_string_free(str);
    return -1;
  }
  ssh_string_free(str);

  if (buffer_add_u32(session->out_buffer, ntohl(row)) < 0 ||
      buffer_add_u32(session->out_buffer, ntohl(col)) < 0 ||
      buffer_add_u32(session->out_buffer, 0) < 0 || /* x */
      buffer_add_u32(session->out_buffer, 0) < 0 || /* y */
      buffer_add_u8(session->out_buffer, 0) < 0) { /* tty things */
    return -1;
  }

  ssh_log(session, SSH_LOG_FUNCTIONS, "Opening a ssh1 pty");
  channel->request_state = SSH_CHANNEL_REQ_STATE_PENDING;
  if (packet_send(session) == SSH_ERROR) {
    return -1;
  }

  while (channel->request_state == SSH_CHANNEL_REQ_STATE_PENDING) {
      ssh_handle_packets(session, SSH_TIMEOUT_INFINITE);
  }

  switch(channel->request_state){
    case SSH_CHANNEL_REQ_STATE_ERROR:
    case SSH_CHANNEL_REQ_STATE_PENDING:
    case SSH_CHANNEL_REQ_STATE_NONE:
      channel->request_state=SSH_CHANNEL_REQ_STATE_NONE;
      return SSH_ERROR;
    case SSH_CHANNEL_REQ_STATE_ACCEPTED:
      channel->request_state=SSH_CHANNEL_REQ_STATE_NONE;
      ssh_log(session, SSH_LOG_RARE, "PTY: Success");
      return SSH_OK;
    case SSH_CHANNEL_REQ_STATE_DENIED:
      channel->request_state=SSH_CHANNEL_REQ_STATE_NONE;
      ssh_set_error(session, SSH_REQUEST_DENIED,
          "Server denied PTY allocation");
      ssh_log(session, SSH_LOG_RARE, "PTY: denied\n");
      return SSH_ERROR;
  }
  // Not reached
  return SSH_ERROR;
}
Ejemplo n.º 30
0
int ssh_message_auth_interactive_request(ssh_message msg, const char *name,
                            const char *instruction, unsigned int num_prompts,
                            const char **prompts, char *echo) {
  int r;
  unsigned int i = 0;
  ssh_string tmp = NULL;

  if(name == NULL || instruction == NULL) {
    return SSH_ERROR;
  }
  if(num_prompts > 0 && (prompts == NULL || echo == NULL)) {
    return SSH_ERROR;
  }

  if (buffer_add_u8(msg->session->out_buffer, SSH2_MSG_USERAUTH_INFO_REQUEST) < 0) {
    return SSH_ERROR;
  }

  /* name */
  tmp = ssh_string_from_char(name);
  if (tmp == NULL) {
      return SSH_ERROR;
  }

  r = buffer_add_ssh_string(msg->session->out_buffer, tmp);
  ssh_string_free(tmp);
  if (r < 0) {
    return SSH_ERROR;
  }

  /* instruction */
  tmp = ssh_string_from_char(instruction);
  if (tmp == NULL) {
      return SSH_ERROR;
  }

  r = buffer_add_ssh_string(msg->session->out_buffer, tmp);
  ssh_string_free(tmp);
  if (r < 0) {
    return SSH_ERROR;
  }

  /* language tag */
  tmp = ssh_string_from_char("");
  if (tmp == NULL) {
      return SSH_ERROR;
  }

  r = buffer_add_ssh_string(msg->session->out_buffer, tmp);
  ssh_string_free(tmp);
  if (r < 0) {
    return SSH_ERROR;
  }

  /* num prompts */
  if (buffer_add_u32(msg->session->out_buffer, ntohl(num_prompts)) < 0) {
    return SSH_ERROR;
  }

  for(i = 0; i < num_prompts; i++) {
    /* prompt[i] */
    tmp = ssh_string_from_char(prompts[i]);
    if (tmp == NULL) {
        return SSH_ERROR;
    }

    r = buffer_add_ssh_string(msg->session->out_buffer, tmp);
    ssh_string_free(tmp);
    if (r < 0) {
        return SSH_ERROR;
    }

    /* echo[i] */
    if (buffer_add_u8(msg->session->out_buffer, echo[i]) < 0) {
        return SSH_ERROR;
    }
  }

  r = packet_send(msg->session);

  /* fill in the kbdint structure */
  if (msg->session->kbdint == NULL) {
    SSH_LOG(SSH_LOG_PROTOCOL, "Warning: Got a "
                                        "keyboard-interactive response but it "
                                        "seems we didn't send the request.");

    msg->session->kbdint = ssh_kbdint_new();
    if (msg->session->kbdint == NULL) {
      ssh_set_error_oom(msg->session);

      return SSH_ERROR;
    }
  } else {
    ssh_kbdint_clean(msg->session->kbdint);
  }

  msg->session->kbdint->name = strdup(name);
  if(msg->session->kbdint->name == NULL) {
      ssh_set_error_oom(msg->session);
      ssh_kbdint_free(msg->session->kbdint);
      msg->session->kbdint = NULL;
      return SSH_PACKET_USED;
  }
  msg->session->kbdint->instruction = strdup(instruction);
  if(msg->session->kbdint->instruction == NULL) {
      ssh_set_error_oom(msg->session);
      ssh_kbdint_free(msg->session->kbdint);
      msg->session->kbdint = NULL;
      return SSH_PACKET_USED;
  }

  msg->session->kbdint->nprompts = num_prompts;
  if(num_prompts > 0) {
    msg->session->kbdint->prompts = malloc(num_prompts * sizeof(char *));
    if (msg->session->kbdint->prompts == NULL) {
      msg->session->kbdint->nprompts = 0;
      ssh_set_error_oom(msg->session);
      ssh_kbdint_free(msg->session->kbdint);
      msg->session->kbdint = NULL;
      return SSH_ERROR;
    }
    msg->session->kbdint->echo = malloc(num_prompts * sizeof(unsigned char));
    if (msg->session->kbdint->echo == NULL) {
      ssh_set_error_oom(msg->session);
      ssh_kbdint_free(msg->session->kbdint);
      msg->session->kbdint = NULL;
      return SSH_ERROR;
    }
    for (i = 0; i < num_prompts; i++) {
      msg->session->kbdint->echo[i] = echo[i];
      msg->session->kbdint->prompts[i] = strdup(prompts[i]);
      if (msg->session->kbdint->prompts[i] == NULL) {
        ssh_set_error_oom(msg->session);
        msg->session->kbdint->nprompts = i;
        ssh_kbdint_free(msg->session->kbdint);
        msg->session->kbdint = NULL;
        return SSH_PACKET_USED;
      }
    }
  } else {
    msg->session->kbdint->prompts = NULL;
    msg->session->kbdint->echo = NULL;
  }

  return r;
}