Beispiel #1
0
/*
 * 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 = string_from_char(msg->auth_request.username);
  ssh_string servicename = string_from_char(service);
  ssh_string method = string_from_char("publickey");
  uint8_t has_sign = 1;
  ssh_string algo = string_from_char(msg->auth_request.public_key->type_c);
  ssh_string publickey = publickey_to_string(msg->auth_request.public_key);

  buffer = buffer_new();
  if (buffer == NULL) {
    goto error;
  }
  session_id = string_new(SHA_DIGEST_LEN);
  if (session_id == NULL) {
    buffer_free(buffer);
    buffer = NULL;
    goto error;
  }
  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) {
    buffer_free(buffer);
    buffer = NULL;
    goto error;
  }

error:
  if(session_id) string_free(session_id);
  if(username) string_free(username);
  if(servicename) string_free(servicename);
  if(method) string_free(method);
  if(algo) string_free(algo);
  if(publickey) string_free(publickey);
  return buffer;
}
Beispiel #2
0
/* this function sends the first packet as explained in section 3.1
 * of the draft */
static int kbdauth_init(SSH_SESSION *session,
        const char *user, const char *submethods){
    STRING *user_s=string_from_char(user);
    STRING *submethods_s=(submethods ? string_from_char(submethods): string_from_char(""));
    STRING *service=string_from_char("ssh-connection");
    STRING *method=string_from_char("keyboard-interactive");
    int err;
    enter_function();
    buffer_add_u8(session->out_buffer,SSH2_MSG_USERAUTH_REQUEST);
    buffer_add_ssh_string(session->out_buffer,user_s);
    buffer_add_ssh_string(session->out_buffer,service);
    buffer_add_ssh_string(session->out_buffer,method);
    buffer_add_u32(session->out_buffer,0); // language tag
    buffer_add_ssh_string(session->out_buffer,submethods_s);
    free(user_s);
    free(service);
    free(method);
    free(submethods_s);
    if(packet_send(session)){
        leave_function();
    	return SSH_AUTH_ERROR;
    }
    err=wait_auth_status(session,1);
    leave_function();
    return err;
}
Beispiel #3
0
/* this function sends the first packet as explained in section 3.1
 * of the draft */
static int kbdauth_init(ssh_session session, const char *user,
    const char *submethods) {
  ssh_string usr = NULL;
  ssh_string sub = NULL;
  ssh_string service = NULL;
  ssh_string method = NULL;
  int rc = SSH_AUTH_ERROR;

  enter_function();

  usr = string_from_char(user);
  if (usr == NULL) {
    goto error;
  }
  sub = (submethods ? string_from_char(submethods) : string_from_char(""));
  if (sub == NULL) {
    goto error;
  }
  service = string_from_char("ssh-connection");
  if (service == NULL) {
    goto error;
  }
  method = string_from_char("keyboard-interactive");
  if (method == NULL) {
    goto error;
  }

  if (buffer_add_u8(session->out_buffer, SSH2_MSG_USERAUTH_REQUEST) < 0 ||
      buffer_add_ssh_string(session->out_buffer, usr) < 0 ||
      buffer_add_ssh_string(session->out_buffer, service) < 0 ||
      buffer_add_ssh_string(session->out_buffer, method) < 0 ||
      buffer_add_u32(session->out_buffer, 0) < 0 ||
      buffer_add_ssh_string(session->out_buffer, sub) < 0) {
    goto error;
  }

  string_free(usr);
  string_free(service);
  string_free(method);
  string_free(sub);

  if (packet_send(session) != SSH_OK) {
    leave_function();
    return rc;
  }
  rc = wait_auth_status(session,1);

  leave_function();
  return rc;
error:
  buffer_reinit(session->out_buffer);
  string_free(usr);
  string_free(service);
  string_free(method);
  string_free(sub);

  leave_function();
  return rc;
}
int sftp_reply_names_add(SFTP_CLIENT_MESSAGE *msg, char *file, char *longname,
                         SFTP_ATTRIBUTES *attr) {
    STRING *name=string_from_char(file);
    if(!msg->attrbuf)
        msg->attrbuf=buffer_new();
    buffer_add_ssh_string(msg->attrbuf,name);
    free(name);
    name=string_from_char(longname);
    buffer_add_ssh_string(msg->attrbuf,name);
    free(name);
    buffer_add_attributes(msg->attrbuf,attr);
    msg->attr_num++;
    return 0;
}
Beispiel #5
0
int ssh_userauth_pubkey(SSH_SESSION *session, const char *username, STRING *publickey, PRIVATE_KEY *privatekey){
    STRING *user;
    STRING *service;
    STRING *method;
    STRING *algo;
    STRING *sign;
    int err=SSH_AUTH_ERROR;
    enter_function();
//    if(session->version==1)
//        return ssh_userauth1_pubkey(session,username,publickey,privatekey);
    if(!username)
        if(!(username=session->options->username)){
            if(ssh_options_default_username(session->options)){
            	leave_function();
            	return err;
            } else
                username=session->options->username;
        }
    if(ask_userauth(session)){
        leave_function();
    	return err;
    }
    user=string_from_char(username);
    service=string_from_char("ssh-connection");
    method=string_from_char("publickey");
    algo=string_from_char(ssh_type_to_char(privatekey->type));


    /* we said previously the public key was accepted */
    buffer_add_u8(session->out_buffer,SSH2_MSG_USERAUTH_REQUEST);
    buffer_add_ssh_string(session->out_buffer,user);
    buffer_add_ssh_string(session->out_buffer,service);
    buffer_add_ssh_string(session->out_buffer,method);
    buffer_add_u8(session->out_buffer,1);
    buffer_add_ssh_string(session->out_buffer,algo);
    buffer_add_ssh_string(session->out_buffer,publickey);
    sign=ssh_do_sign(session,session->out_buffer,privatekey);
    if(sign){
        buffer_add_ssh_string(session->out_buffer,sign);
        free(sign);
        packet_send(session);
        err=wait_auth_status(session,0);
    }
    free(user);
    free(service);
    free(method);
    free(algo);
    leave_function();
    return err;
}
Beispiel #6
0
int ssh_userauth_password(SSH_SESSION *session, const char *username, const char *password){
    STRING *user;
    STRING *service;
    STRING *method;
    STRING *password_s;
    int err;
    enter_function();
#ifdef HAVE_SSH1
    if(session->version==1){
        err = ssh_userauth1_password(session,username,password);
        leave_function();
        return err;
    }
#endif
    if(!username)
        if(!(username=session->options->username)){
            if(ssh_options_default_username(session->options)){
                err = SSH_AUTH_ERROR;
                leave_function();
                return err;
            } else
                username=session->options->username;
        }
    if(ask_userauth(session)){
    	leave_function();
    	return SSH_AUTH_ERROR;
    }
    user=string_from_char(username);
    service=string_from_char("ssh-connection");
    method=string_from_char("password");
    password_s=string_from_char(password);

    buffer_add_u8(session->out_buffer,SSH2_MSG_USERAUTH_REQUEST);
    buffer_add_ssh_string(session->out_buffer,user);
    buffer_add_ssh_string(session->out_buffer,service);
    buffer_add_ssh_string(session->out_buffer,method);
    buffer_add_u8(session->out_buffer,0);
    buffer_add_ssh_string(session->out_buffer,password_s);
    free(user);
    free(service);
    free(method);
    memset(password_s,0,strlen(password)+4);
    free(password_s);
    packet_send(session);
    err=wait_auth_status(session,0);
    leave_function();
    return err;
}
Beispiel #7
0
/**
 * @brief Run a shell command without an interactive shell.
 *
 * This is similar to 'sh -c command'.
 *
 * @param channel       The channel to execute the command.
 *
 * @param cmd           The command to execute
 *                      (e.g. "ls ~/ -al | grep -i reports").
 *
 * @return SSH_SUCCESS on success, SSH_ERROR on error.
 *
 * @see channel_request_shell()
 */
int channel_request_exec(CHANNEL *channel, const char *cmd) {
  BUFFER *buffer = NULL;
  STRING *command = NULL;
  int rc = SSH_ERROR;

#ifdef HAVE_SSH1
  if (channel->version == 1) {
    return channel_request_exec1(channel, cmd);
  }
#endif

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

  command = string_from_char(cmd);
  if (command == NULL) {
    goto error;
  }

  if (buffer_add_ssh_string(buffer, command) < 0) {
    goto error;
  }

  rc = channel_request(channel, "exec", buffer, 1);
error:
  buffer_free(buffer);
  string_free(command);
  return rc;
}
Beispiel #8
0
/* this is a public key in openssh's format */
static STRING *make_rsa1_string(STRING *e, STRING *n){
  BUFFER *buffer = NULL;
  STRING *rsa = NULL;
  STRING *ret = NULL;

  buffer = buffer_new();
  rsa = string_from_char("ssh-rsa1");

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

  ret = string_new(buffer_get_len(buffer));
  if (ret == NULL) {
    goto error;
  }

  string_fill(ret, buffer_get(buffer), buffer_get_len(buffer));
error:
  buffer_free(buffer);
  string_free(rsa);

  return ret;
}
Beispiel #9
0
/**
 * @brief Request a subsystem (for example "sftp").
 *
 * @param channel       The channel to send the request.
 *
 * @param system        The subsystem to request (for example "sftp").
 *
 * @return SSH_SUCCESS on success, SSH_ERROR on error.
 *
 * @warning You normally don't have to call it for sftp, see sftp_new().
 */
int channel_request_subsystem(CHANNEL *channel, const char *sys) {
  BUFFER *buffer = NULL;
  STRING *subsystem = NULL;
  int rc = SSH_ERROR;

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

  subsystem = string_from_char(sys);
  if (subsystem == NULL) {
    goto error;
  }

  if (buffer_add_ssh_string(buffer, subsystem) < 0) {
    goto error;
  }

  rc = channel_request(channel, "subsystem", buffer, 1);
error:
  buffer_free(buffer);
  string_free(subsystem);

  return rc;
}
Beispiel #10
0
int ssh_userauth_offer_pubkey(SSH_SESSION *session, const char *username,int type, STRING *publickey){
    STRING *user;
    STRING *service;
    STRING *method;
    STRING *algo;
    int err=SSH_AUTH_ERROR;
    enter_function();
#ifdef HAVE_SSH1
    if(session->version==1){
        err= ssh_userauth1_offer_pubkey(session,username,type,publickey);
        leave_function();
        return err;
    }
#endif
    if(!username)
        if(!(username=session->options->username)){
            if(ssh_options_default_username(session->options)){
                leave_function();
            	return SSH_AUTH_ERROR;
            } else
                username=session->options->username;
        }
    if(ask_userauth(session)){
        leave_function();
    	return SSH_AUTH_ERROR;
    }
    user=string_from_char(username);
    service=string_from_char("ssh-connection");
    method=string_from_char("publickey");
    algo=string_from_char(ssh_type_to_char(type));

    buffer_add_u8(session->out_buffer,SSH2_MSG_USERAUTH_REQUEST);
    buffer_add_ssh_string(session->out_buffer,user);
    buffer_add_ssh_string(session->out_buffer,service);
    buffer_add_ssh_string(session->out_buffer,method);
    buffer_add_u8(session->out_buffer,0);
    buffer_add_ssh_string(session->out_buffer,algo);
    buffer_add_ssh_string(session->out_buffer,publickey);
    packet_send(session);
    err=wait_auth_status(session,0);
    free(user);
    free(method);
    free(service);
    free(algo);
    leave_function();
    return err;
}
Beispiel #11
0
/* sends challenge back to the server */
static int kbdauth_send(ssh_session session) {
  ssh_string answer = NULL;
  int rc = SSH_AUTH_ERROR;
  uint32_t i;

  enter_function();

  if (buffer_add_u8(session->out_buffer, SSH2_MSG_USERAUTH_INFO_RESPONSE) < 0 ||
      buffer_add_u32(session->out_buffer,
        htonl(session->kbdint->nprompts)) < 0) {
    goto error;
  }

  for (i = 0; i < session->kbdint->nprompts; i++) {
    if (session->kbdint->answers[i]) {
      answer = string_from_char(session->kbdint->answers[i]);
    } else {
      answer = string_from_char("");
    }
    if (answer == NULL) {
      goto error;
    }

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

    string_burn(answer);
    string_free(answer);
  }

  if (packet_send(session) != SSH_OK) {
    leave_function();
    return rc;
  }
  rc = wait_auth_status(session,1);

  leave_function();
  return rc;
error:
  buffer_reinit(session->out_buffer);
  string_burn(answer);
  string_free(answer);

  leave_function();
  return rc;
}
Beispiel #12
0
/* this function only sends the predefined set of kex methods */
int ssh_send_kex(SSH_SESSION *session, int server_kex) {
  KEX *kex = (server_kex ? &session->server_kex : &session->client_kex);
  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 < 10; i++) {
    str = 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;
    }
    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_OK) {
    leave_function();
    return -1;
  }

  leave_function();
  return 0;
error:
  buffer_free(session->out_buffer);
  buffer_free(session->out_hashbuf);
  string_free(str);

  leave_function();
  return -1;
}
Beispiel #13
0
/**
 * @brief Open a TCP/IP forwarding channel.
 *
 * @param channel       An allocated channel.
 *
 * @param remotehost    The remote host to connected (host name or IP).
 *
 * @param remoteport    The remote port.
 *
 * @param sourcehost    The source host (your local computer). It's facultative
 *                      and for logging purpose.
 *
 * @param localport     The source port (your local computer). It's facultative
 *                      and for logging purpose.
 *
 * @return SSH_OK on success\n
 *         SSH_ERROR on error
 */
int channel_open_forward(CHANNEL *channel, const char *remotehost,
    int remoteport, const char *sourcehost, int localport) {
  SSH_SESSION *session = channel->session;
  BUFFER *payload = NULL;
  STRING *str = NULL;
  int rc = SSH_ERROR;

  enter_function();

  payload = buffer_new();
  if (payload == NULL) {
    goto error;
  }
  str = string_from_char(remotehost);
  if (str == NULL) {
    goto error;
  }

  if (buffer_add_ssh_string(payload, str) < 0 ||
      buffer_add_u32(payload,htonl(remoteport)) < 0) {
    goto error;
  }

  string_free(str);
  str = string_from_char(sourcehost);
  if (str == NULL) {
    goto error;
  }

  if (buffer_add_ssh_string(payload, str) < 0 ||
      buffer_add_u32(payload,htonl(localport)) < 0) {
    goto error;
  }

  rc = channel_open(channel, "direct-tcpip", 64000, 32000, payload);

error:
  buffer_free(payload);
  string_free(str);

  leave_function();
  return rc;
}
Beispiel #14
0
int ssh_userauth_none(SSH_SESSION *session, const char *username){
    STRING *user;
    STRING *service;
    STRING *method;
    int ret;
    enter_function();
#ifdef HAVE_SSH1
    if(session->version==1){
        ret = ssh_userauth1_none(session,username);
        leave_function();
        return ret;
    }
#endif
    if(!username)
        if(!(username=session->options->username)){
            if(ssh_options_default_username(session->options)){
                leave_function();
            	return SSH_AUTH_ERROR;
            } else
                username=session->options->username;
        }
    if(ask_userauth(session)){
    	leave_function();
    	return SSH_AUTH_ERROR;
    }
    user=string_from_char(username);
    method=string_from_char("none");
    service=string_from_char("ssh-connection");
    buffer_add_u8(session->out_buffer,SSH2_MSG_USERAUTH_REQUEST);
    buffer_add_ssh_string(session->out_buffer,user);
    buffer_add_ssh_string(session->out_buffer,service);
    buffer_add_ssh_string(session->out_buffer,method);
    free(service);
    free(method);
    free(user);
    packet_send(session);
    ret = wait_auth_status(session,0);
    leave_function();
    return ret;
}
Beispiel #15
0
int channel_request_pty_size1(ssh_channel channel, const char *terminal, int col,
    int row) {
  ssh_session session = channel->session;
  ssh_string str = NULL;

  str = string_from_char(terminal);
  if (str == NULL) {
    return -1;
  }

  if (buffer_add_u8(session->out_buffer, SSH_CMSG_REQUEST_PTY) < 0 ||
      buffer_add_ssh_string(session->out_buffer, str) < 0) {
    string_free(str);
    return -1;
  }
  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");
  if (packet_send(session) != SSH_OK ||
      packet_read(session) != SSH_OK ||
      packet_translate(session) != SSH_OK) {
    return -1;
  }

  switch (session->in_packet.type) {
    case SSH_SMSG_SUCCESS:
      ssh_log(session, SSH_LOG_RARE, "PTY: Success");
      return 0;
      break;
    case SSH_SMSG_FAILURE:
      ssh_set_error(session, SSH_REQUEST_DENIED,
          "Server denied PTY allocation");
      ssh_log(session, SSH_LOG_RARE, "PTY: denied\n");
      break;
    default:
      ssh_log(session, SSH_LOG_RARE, "PTY: error\n");
      ssh_set_error(session, SSH_FATAL,
          "Received unexpected packet type %d",
          session->in_packet.type);
      return -1;
  }

  return -1;
}
Beispiel #16
0
/* this is a public key in openssh's format */
static STRING *make_rsa1_string(STRING *e, STRING *n){
    BUFFER *buffer=buffer_new();
    STRING *rsa=string_from_char("ssh-rsa1");
    STRING *ret;
    buffer_add_ssh_string(buffer,rsa);
    free(rsa);
    buffer_add_ssh_string(buffer,e);
    buffer_add_ssh_string(buffer,n);
    ret=string_new(buffer_get_len(buffer));
    string_fill(ret,buffer_get(buffer),buffer_get_len(buffer));
    buffer_free(buffer);
    return ret;
}
int sftp_reply_name(SFTP_CLIENT_MESSAGE *msg, char *name, SFTP_ATTRIBUTES *attr) {
    BUFFER *out=buffer_new();
    STRING *file=string_from_char(name);
    int r;
    buffer_add_u32(out,msg->id);
    buffer_add_u32(out,htonl(1));
    buffer_add_ssh_string(out,file);
    buffer_add_ssh_string(out,file); /* the protocol is broken here between 3 & 4 */
    free(file);
    buffer_add_attributes(out,attr);
    r=sftp_packet_write(msg->sftp,SSH_FXP_NAME,out);
    buffer_free(out);
    return r<0;
}
int sftp_reply_status(SFTP_CLIENT_MESSAGE *msg, u32 status, char *message) {
    BUFFER *out=buffer_new();
    int r;
    STRING *s;
    buffer_add_u32(out,msg->id);
    buffer_add_u32(out,htonl(status));
    s=string_from_char(message?message:"");
    buffer_add_ssh_string(out,s);
    free(s);
    buffer_add_u32(out,0); // language string
    r=sftp_packet_write(msg->sftp,SSH_FXP_STATUS,out);
    buffer_free(out);
    return r<0;
}
Beispiel #19
0
/**
 * @brief Set environement variables.
 *
 * @param channel       The channel to set the environement variables.
 *
 * @param name          The name of the variable.
 *
 * @param value         The value to set.
 *
 * @return SSH_SUCCESS on success, SSH_ERROR on error.
 *
 * @warning Some environement variables may be refused by security reasons.
 * */
int channel_request_env(CHANNEL *channel, const char *name, const char *value) {
  BUFFER *buffer = NULL;
  STRING *str = NULL;
  int rc = SSH_ERROR;

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

  str = string_from_char(name);
  if (str == NULL) {
    goto error;
  }

  if (buffer_add_ssh_string(buffer, str) < 0) {
    goto error;
  }

  string_free(str);
  str = string_from_char(value);
  if (str == NULL) {
    goto error;
  }

  if (buffer_add_ssh_string(buffer, str) < 0) {
    goto error;
  }

  rc = channel_request(channel, "env", buffer,1);
error:
  buffer_free(buffer);
  string_free(str);

  return rc;
}
Beispiel #20
0
/* sends challenge back to the server */
static int kbdauth_send(SSH_SESSION *session) {
    STRING *answer;
    u32 i;
    int err;
    enter_function();
    buffer_add_u8(session->out_buffer,SSH2_MSG_USERAUTH_INFO_RESPONSE);
    buffer_add_u32(session->out_buffer,htonl(session->kbdint->nprompts));
    for(i=0;i<session->kbdint->nprompts;++i){
        if(session->kbdint->answers[i])
            answer=string_from_char(session->kbdint->answers[i]);
        else
            answer=string_from_char("");
        buffer_add_ssh_string(session->out_buffer,answer);
        string_burn(answer);
        free(answer);
    }
    if(packet_send(session)){
        leave_function();
    	return SSH_AUTH_ERROR;
    }
    err = wait_auth_status(session,1);
    leave_function();
    return err;
}
Beispiel #21
0
/** \brief disconnect from a session (client or server)
 * \param session ssh session
 */
void ssh_disconnect(SSH_SESSION *session){
    STRING *str;
    if(session->fd!= -1) {
        packet_clear_out(session);
        buffer_add_u8(session->out_buffer,SSH2_MSG_DISCONNECT);
        buffer_add_u32(session->out_buffer,htonl(SSH2_DISCONNECT_BY_APPLICATION));
        str=string_from_char("Bye Bye");
        buffer_add_ssh_string(session->out_buffer,str);
        free(str);
        packet_send(session);
        close(session->fd);
        session->fd=-1;
    }
    session->alive=0;
    ssh_cleanup(session);
}
Beispiel #22
0
int ssh_service_request(SSH_SESSION *session,char *service){
    STRING *service_s;
    packet_clear_out(session);
    buffer_add_u8(session->out_buffer,SSH2_MSG_SERVICE_REQUEST);
    service_s=string_from_char(service);
    buffer_add_ssh_string(session->out_buffer,service_s);
    free(service_s);
    packet_send(session);
    ssh_say(3,"Sent SSH_MSG_SERVICE_REQUEST (service %s)\n",service);
    if(packet_wait(session,SSH2_MSG_SERVICE_ACCEPT,1)){
        ssh_set_error(session,SSH_FATAL,"did not receive SERVICE_ACCEPT");
        return -1;
    }
    ssh_say(3,"Received SSH_MSG_SERVICE_ACCEPT (service %s)\n",service);
    return 0;
}
Beispiel #23
0
/** \brief makes a SSH String out of a PUBLIC_KEY object
 * \param key the public key
 * \returns a SSH String containing the public key
 * \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 = buffer_new();
  if (buf == NULL) {
    return NULL;
  }

  type = 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 TYPE_DSS:
      if (dsa_public_to_string(key->dsa_pub, buf) < 0) {
        goto error;
      }
      break;
    case TYPE_RSA:
    case TYPE_RSA1:
      if (rsa_public_to_string(key->rsa_pub, buf) < 0) {
        goto error;
      }
      break;
  }

  ret = string_new(buffer_get_len(buf));
  if (ret == NULL) {
    goto error;
  }

  string_fill(ret, buffer_get(buf), buffer_get_len(buf));
error:
  buffer_free(buf);
  string_free(type);

  return ret;
}
Beispiel #24
0
/**
 * @brief Request a pty with a specific type and size.
 *
 * @param channel       The channel to sent the request.
 *
 * @param terminal      The terminal type ("vt100, xterm,...").
 *
 * @param col           The number of columns.
 *
 * @param row           The number of rows.
 *
 * @return SSH_SUCCESS on success, SSH_ERROR on error.
 */
int channel_request_pty_size(CHANNEL *channel, const char *terminal,
    int col, int row) {
  SSH_SESSION *session = channel->session;
  STRING *term = NULL;
  BUFFER *buffer = NULL;
  int rc = SSH_ERROR;

  enter_function();
#ifdef HAVE_SSH1
  if (channel->version==1) {
    channel_request_pty_size1(channel,terminal, col, row);
    leave_function();
    return rc;
    }
#endif
  buffer = buffer_new();
  if (buffer == NULL) {
    goto error;
  }

  term = string_from_char(terminal);
  if (term == NULL) {
    goto error;
  }

  if (buffer_add_ssh_string(buffer, term) < 0 ||
      buffer_add_u32(buffer, htonl(col)) < 0 ||
      buffer_add_u32(buffer, htonl(row)) < 0 ||
      buffer_add_u32(buffer, 0) < 0 ||
      buffer_add_u32(buffer, 0) < 0 ||
      buffer_add_u32(buffer, htonl(1)) < 0 || /* Add a 0byte string */
      buffer_add_u8(buffer, 0) < 0) {
    goto error;
  }

  rc = channel_request(channel, "pty-req", buffer, 1);
error:
  buffer_free(buffer);
  string_free(term);

  leave_function();
  return rc;
}
Beispiel #25
0
/* this function only sends the predefined set of kex methods */    
void ssh_send_kex(SSH_SESSION *session, int server_kex){
    STRING *str;
    int i=0;
    KEX *kex=(server_kex ? &session->server_kex : &session->client_kex);
    packet_clear_out(session);
    buffer_add_u8(session->out_buffer,SSH2_MSG_KEXINIT);
    buffer_add_data(session->out_buffer,kex->cookie,16);
    hashbufout_add_cookie(session);
    ssh_list_kex(kex);
    for(i=0;i<10;i++){
        str=string_from_char(kex->methods[i]);
        buffer_add_ssh_string(session->out_hashbuf,str);
        buffer_add_ssh_string(session->out_buffer,str);
        free(str);
    }
    i=0;
    buffer_add_u8(session->out_buffer,0);
    buffer_add_u32(session->out_buffer,0);
    packet_send(session);
}
Beispiel #26
0
/** \brief makes a SSH String out of a PUBLIC_KEY object
 * \param key the public key
 * \returns a SSH String containing the public key
 * \see string_free()
 */
STRING *publickey_to_string(PUBLIC_KEY *key){
    STRING *type;
    STRING *ret;
    BUFFER *buf;
    type=string_from_char(ssh_type_to_char(key->type));
    buf=buffer_new();
    buffer_add_ssh_string(buf,type);
    switch(key->type){
        case TYPE_DSS:
            dsa_public_to_string(key->dsa_pub,buf);
            break;
        case TYPE_RSA:
        case TYPE_RSA1:
            rsa_public_to_string(key->rsa_pub,buf);
            break;
    }
    ret=string_new(buffer_get_len(buf));
    string_fill(ret,buffer_get(buf),buffer_get_len(buf));
    buffer_free(buf);
    free(type);
    return ret;
}
Beispiel #27
0
int channel_request_exec1(ssh_channel channel, const char *cmd) {
  ssh_session session = channel->session;
  ssh_string command = NULL;

  command = 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) {
    string_free(command);
    return -1;
  }
  string_free(command);

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

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

  return 0;
}
Beispiel #28
0
STRING *signature_to_string(SIGNATURE *sign){
    STRING *str;
    STRING *rs;
#ifdef HAVE_LIBGCRYPT
    const char *r,*s;
    gcry_sexp_t sexp;
    size_t size;
#elif defined HAVE_LIBCRYPTO
    STRING *r,*s;
#endif
    unsigned char buffer[40];
    BUFFER *tmpbuf=buffer_new();
    STRING *tmp;
    tmp=string_from_char(ssh_type_to_char(sign->type));
    buffer_add_ssh_string(tmpbuf,tmp);
    free(tmp);
    switch(sign->type){
        case TYPE_DSS:
            memset(buffer,0,40);
#ifdef HAVE_LIBGCRYPT
            sexp=gcry_sexp_find_token(sign->dsa_sign,"r",0);
            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);
            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);
            s=make_bignum_string(sign->dsa_sign->s);
            rs=string_new(40);
            memcpy(buffer,r->string+string_len(r)-20,20);
            memcpy(buffer+ 20, s->string + string_len(s) - 20, 20);
            free(r);
            free(s);
#endif
            rs=string_new(40);
            string_fill(rs,buffer,40);
            buffer_add_ssh_string(tmpbuf,rs);
            free(rs);
            break;
        case TYPE_RSA:
        case TYPE_RSA1:
#ifdef HAVE_LIBGCRYPT
            sexp=gcry_sexp_find_token(sign->rsa_sign,"s",0);
            s=gcry_sexp_nth_data(sexp,1,&size);
            if (*s == 0)
            {
              size--;
              s++;
            }
            rs=string_new(size);
            string_fill(rs,(char *)s,size);
            buffer_add_ssh_string(tmpbuf,rs);
            gcry_sexp_release(sexp);
            free(rs);
#elif defined HAVE_LIBCRYPTO
            buffer_add_ssh_string(tmpbuf,sign->rsa_sign);
#endif 
            break;
    }
    str=string_new(buffer_get_len(tmpbuf));
    string_fill(str,buffer_get(tmpbuf),buffer_get_len(tmpbuf));
    buffer_free(tmpbuf);
    return str;
}
Beispiel #29
0
static int channel_open(CHANNEL *channel, const char *type_c, int window,
    int maxpacket, BUFFER *payload) {
  SSH_SESSION *session = channel->session;
  STRING *type = NULL;
  u32 tmp = 0;

  enter_function();

  channel->local_channel = ssh_channel_new_id(session);
  channel->local_maxpacket = maxpacket;
  channel->local_window = window;

  ssh_log(session, SSH_LOG_RARE,
      "Creating a channel %d with %d window and %d max packet",
      channel->local_channel, window, maxpacket);

  type = string_from_char(type_c);
  if (type == NULL) {
    leave_function();
    return -1;
  }

  if (buffer_add_u8(session->out_buffer, SSH2_MSG_CHANNEL_OPEN) < 0 ||
      buffer_add_ssh_string(session->out_buffer,type) < 0 ||
      buffer_add_u32(session->out_buffer, htonl(channel->local_channel)) < 0 ||
      buffer_add_u32(session->out_buffer, htonl(channel->local_window)) < 0 ||
      buffer_add_u32(session->out_buffer, htonl(channel->local_maxpacket)) < 0) {
    string_free(type);
    leave_function();
    return -1;
  }

  string_free(type);

  if (payload != NULL) {
    if (buffer_add_buffer(session->out_buffer, payload) < 0) {
      leave_function();
      return -1;
    }
  }

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

  ssh_log(session, SSH_LOG_RARE,
      "Sent a SSH_MSG_CHANNEL_OPEN type %s for channel %d",
      type_c, channel->local_channel);

  if (packet_wait(session, SSH2_MSG_CHANNEL_OPEN_CONFIRMATION, 1) != SSH_OK) {
    leave_function();
    return -1;
  }

  switch(session->in_packet.type) {
    case SSH2_MSG_CHANNEL_OPEN_CONFIRMATION:
      buffer_get_u32(session->in_buffer, &tmp);

      if (channel->local_channel != ntohl(tmp)) {
        ssh_set_error(session, SSH_FATAL,
            "Server answered with sender channel number %lu instead of given %u",
            (long unsigned int) ntohl(tmp),
            channel->local_channel);
        leave_function();
        return -1;
      }
      buffer_get_u32(session->in_buffer, &tmp);
      channel->remote_channel = ntohl(tmp);

      buffer_get_u32(session->in_buffer, &tmp);
      channel->remote_window = ntohl(tmp);

      buffer_get_u32(session->in_buffer,&tmp);
      channel->remote_maxpacket=ntohl(tmp);

      ssh_log(session, SSH_LOG_PROTOCOL,
          "Received a CHANNEL_OPEN_CONFIRMATION for channel %d:%d",
          channel->local_channel,
          channel->remote_channel);
      ssh_log(session, SSH_LOG_PROTOCOL,
          "Remote window : %lu, maxpacket : %lu",
          (long unsigned int) channel->remote_window,
          (long unsigned int) channel->remote_maxpacket);

      channel->open = 1;
      leave_function();
      return 0;
    case SSH2_MSG_CHANNEL_OPEN_FAILURE:
      {
        STRING *error_s;
        char *error;
        u32 code;

        buffer_get_u32(session->in_buffer, &tmp);
        buffer_get_u32(session->in_buffer, &code);

        error_s = buffer_get_ssh_string(session->in_buffer);
        error = string_to_char(error_s);
        string_free(error_s);
        if (error == NULL) {
          leave_function();
          return -1;
        }

        ssh_set_error(session, SSH_REQUEST_DENIED,
            "Channel opening failure: channel %u error (%lu) %s",
            channel->local_channel,
            (long unsigned int) ntohl(code),
            error);
        SAFE_FREE(error);

        leave_function();
        return -1;
      }
    default:
      ssh_set_error(session, SSH_FATAL,
          "Received unknown packet %d\n", session->in_packet.type);
      leave_function();
      return -1;
  }

  leave_function();
  return -1;
}
Beispiel #30
0
static int channel_request(CHANNEL *channel, const char *request,
    BUFFER *buffer, int reply) {
  SSH_SESSION *session = channel->session;
  STRING *req = NULL;
  int rc = SSH_ERROR;

  enter_function();

  req = string_from_char(request);
  if (req == NULL) {
    goto error;
  }

  if (buffer_add_u8(session->out_buffer, SSH2_MSG_CHANNEL_REQUEST) < 0 ||
      buffer_add_u32(session->out_buffer, htonl(channel->remote_channel)) < 0 ||
      buffer_add_ssh_string(session->out_buffer, req) < 0 ||
      buffer_add_u8(session->out_buffer, reply == 0 ? 0 : 1) < 0) {
    goto error;
  }
  string_free(req);

  if (buffer != NULL) {
    if (buffer_add_data(session->out_buffer, buffer_get(buffer),
        buffer_get_len(buffer)) < 0) {
      goto error;
    }
  }

  if (packet_send(session) != SSH_OK) {
    leave_function();
    return rc;
  }

  ssh_log(session, SSH_LOG_RARE,
      "Sent a SSH_MSG_CHANNEL_REQUEST %s", request);
  if (reply == 0) {
    leave_function();
    return SSH_OK;
  }

  rc = packet_wait(session, SSH2_MSG_CHANNEL_SUCCESS, 1);
  if (rc) {
    if (session->in_packet.type == SSH2_MSG_CHANNEL_FAILURE) {
      ssh_log(session, SSH_LOG_PACKET,
          "%s channel request failed", request);
      ssh_set_error(session, SSH_REQUEST_DENIED,
          "Channel request %s failed", request);
    } else {
      ssh_log(session, SSH_LOG_RARE,
          "Received an unexpected %d message", session->in_packet.type);
    }
  } else {
    ssh_log(session, SSH_LOG_RARE, "Received a SUCCESS");
  }

  leave_function();
  return rc;
error:
  buffer_free(session->out_buffer);
  string_free(req);

  leave_function();
  return rc;
}