Example #1
0
static int kbdauth_info_get(SSH_SESSION *session){
    STRING *name; /* name of the "asking" window showed to client */
    STRING *instruction;
    STRING *tmp;
    u32 nprompts;
    u32 i;
    enter_function();
    name=buffer_get_ssh_string(session->in_buffer);
    instruction=buffer_get_ssh_string(session->in_buffer);
    tmp=buffer_get_ssh_string(session->in_buffer);
    buffer_get_u32(session->in_buffer,&nprompts);
    if(!name || !instruction || !tmp){
        if(name)
            free(name);
        if(instruction)
            free(instruction);
        // tmp must be empty if we got here
        ssh_set_error(session,SSH_FATAL,"Invalid USERAUTH_INFO_REQUEST msg");
        leave_function();
        return SSH_AUTH_ERROR;
    }
    if(tmp)
        free(tmp); // no use
    if(!session->kbdint)
        session->kbdint=kbdint_new();
    else
        kbdint_clean(session->kbdint);
    session->kbdint->name=string_to_char(name);
    free(name);
    session->kbdint->instruction=string_to_char(instruction);
    free(instruction);
    nprompts=ntohl(nprompts);
    if(nprompts>KBDINT_MAX_PROMPT){
        ssh_set_error(session,SSH_FATAL,"Too much prompt asked from server: %lu(0x%.8lx)",nprompts,nprompts);
        leave_function();
        return SSH_AUTH_ERROR;
    }
    session->kbdint->nprompts=nprompts;
    session->kbdint->prompts=malloc(nprompts*sizeof(char *));
    memset(session->kbdint->prompts,0,nprompts*sizeof(char *));
    session->kbdint->echo=malloc(nprompts);
    memset(session->kbdint->echo,0,nprompts);
    for(i=0;i<nprompts;++i){
        tmp=buffer_get_ssh_string(session->in_buffer);
        buffer_get_u8(session->in_buffer,&session->kbdint->echo[i]);
        if(!tmp){
            ssh_set_error(session,SSH_FATAL,"Short INFO_REQUEST packet");
            leave_function();
            return SSH_AUTH_ERROR;
        }
        session->kbdint->prompts[i]=string_to_char(tmp);
        free(tmp);
    }
    leave_function();
    return SSH_AUTH_INFO; /* we are not auth. but we parsed the packet */
}
Example #2
0
PUBLIC_KEY *publickey_from_string(SSH_SESSION *session, STRING *pubkey_s){
    BUFFER *tmpbuf=buffer_new();
    STRING *type_s;
    char *type;

    buffer_add_data(tmpbuf,pubkey_s->string,string_len(pubkey_s));
    type_s=buffer_get_ssh_string(tmpbuf);
    if(!type_s){
        buffer_free(tmpbuf);
        ssh_set_error(session,SSH_FATAL,"Invalid public key format");
        return NULL;
    }
    type=string_to_char(type_s);
    free(type_s);
    if(!strcmp(type,"ssh-dss")){
        free(type);
        return publickey_make_dss(session, tmpbuf);
    }
    if(!strcmp(type,"ssh-rsa")){
        free(type);
        return publickey_make_rsa(session, tmpbuf,"ssh-rsa");
    }
    if(!strcmp(type,"ssh-rsa1")){
        free(type);
        return publickey_make_rsa(session, tmpbuf,"ssh-rsa1");
    }
    ssh_set_error(session,SSH_FATAL,"unknown public key protocol %s",type);
    buffer_free(tmpbuf);
    free(type);
    return NULL;
}
Example #3
0
int ssh_get_kex(SSH_SESSION *session,int server_kex ){
    STRING *str;
    char *strings[10];
    int i;
    if(packet_wait(session,SSH2_MSG_KEXINIT,1))
        return -1;
    if(buffer_get_data(session->in_buffer,session->server_kex.cookie,16)!=16){
        ssh_set_error(session,SSH_FATAL,"get_kex(): no cookie in packet");
        return -1;
    }
    hashbufin_add_cookie(session,session->server_kex.cookie);
    memset(strings,0,sizeof(char *)*10);
    for(i=0;i<10;++i){
        str=buffer_get_ssh_string(session->in_buffer);
        if(!str)
            break;
        if(str){
            buffer_add_ssh_string(session->in_hashbuf,str);
            strings[i]=string_to_char(str);
            free(str);
        } else
            strings[i]=NULL;
    }
    /* copy the server kex info into an array of strings */
    if(server_kex){
        session->client_kex.methods=malloc( 10 * sizeof(char **));
        for(i=0;i<10;++i)
            session->client_kex.methods[i]=strings[i];
    } else { // client     
        session->server_kex.methods=malloc( 10 * sizeof(char **));
        for(i=0;i<10;++i)
            session->server_kex.methods[i]=strings[i];
    }
    return 0;
}
Example #4
0
/*
 * Print a button
 */
static void
print_button(WINDOW *win, char *label, int y, int x, int selected)
{
    int i;
    int state = 0;
    const int *indx = dlg_index_wchars(label);
    int limit = dlg_count_wchars(label);
    chtype key_attr = (selected
		       ? button_key_active_attr
		       : button_key_inactive_attr);
    chtype label_attr = (selected
			 ? button_label_active_attr
			 : button_label_inactive_attr);

    (void) wmove(win, y, x);
    wattrset(win, selected
	     ? button_active_attr
	     : button_inactive_attr);
    (void) waddstr(win, "<");
    wattrset(win, label_attr);
    for (i = 0; i < limit; ++i) {
	int first = indx[i];
	int last = indx[i + 1];

	switch (state) {
	case 0:
#ifdef USE_WIDE_CURSES
	    if ((last - first) != 1) {
		const char *temp = (label + first);
		int cmp = string_to_char(&temp);
		if (dlg_isupper(cmp)) {
		    wattrset(win, key_attr);
		    state = 1;
		}
		break;
	    }
#endif
	    if (dlg_isupper(UCH(label[first]))) {
		wattrset(win, key_attr);
		state = 1;
	    }
	    break;
	case 1:
	    wattrset(win, label_attr);
	    state = 2;
	    break;
	}
	waddnstr(win, label + first, last - first);
    }
    wattrset(win, selected
	     ? button_active_attr
	     : button_inactive_attr);
    (void) waddstr(win, ">");
    (void) wmove(win, y, x + ((int) strspn(label, " ")) + 1);
}
Example #5
0
/*
 * Find the first uppercase character in the label, which we may use for an
 * abbreviation.
 */
int
dlg_button_to_char(const char *label)
{
    int cmp = -1;

    while (*label != 0) {
	cmp = string_to_char(&label);
	if (dlg_isupper(cmp)) {
	    break;
	}
    }
    return cmp;
}
Example #6
0
/* caller has to free commment */
struct ssh_public_key_struct *agent_get_next_ident(struct ssh_session_struct *session,
    char **comment) {
  struct ssh_public_key_struct *pubkey = NULL;
  struct ssh_string_struct *blob = NULL;
  struct ssh_string_struct *tmp = NULL;

  if (session->agent->count == 0) {
    return NULL;
  }

  switch(session->version) {
    case 1:
      return NULL;
    case 2:
      /* get the blob */
      blob = buffer_get_ssh_string(session->agent->ident);
      if (blob == NULL) {
        return NULL;
      }

      /* get the comment */
      tmp = buffer_get_ssh_string(session->agent->ident);
      if (tmp == NULL) {
        string_free(blob);

        return NULL;
      }

      if (comment) {
        *comment = string_to_char(tmp);
      } else {
        string_free(blob);
        string_free(tmp);

        return NULL;
      }
      string_free(tmp);

      /* get key from blob */
      pubkey = publickey_from_string(session, blob);
      string_free(blob);
      break;
    default:
      return NULL;
  }

  return pubkey;
}
Example #7
0
ssh_public_key publickey_from_string(ssh_session session, ssh_string pubkey_s) {
  ssh_buffer tmpbuf = NULL;
  ssh_string type_s = NULL;
  char *type_c = NULL;
  int type;

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

  if (buffer_add_data(tmpbuf, string_data(pubkey_s), string_len(pubkey_s)) < 0) {
    goto error;
  }

  type_s = buffer_get_ssh_string(tmpbuf);
  if (type_s == NULL) {
    ssh_set_error(session,SSH_FATAL,"Invalid public key format");
    goto error;
  }

  type_c = string_to_char(type_s);
  string_free(type_s);
  if (type_c == NULL) {
    goto error;
  }

  type = ssh_type_from_name(type_c);
  SAFE_FREE(type_c);

  switch (type) {
    case TYPE_DSS:
      return publickey_make_dss(session, tmpbuf);
    case TYPE_RSA:
    case TYPE_RSA1:
      return publickey_make_rsa(session, tmpbuf, type);
  }

  ssh_set_error(session, SSH_FATAL, "Unknown public key protocol %s",
      ssh_type_to_char(type));

error:
  buffer_free(tmpbuf);
  return NULL;
}
Example #8
0
/*
 * Match a given character against the beginning of the string, ignoring case
 * of the given character.  The matching string must begin with an uppercase
 * character.
 */
int
dlg_match_char(int ch, const char *string)
{
    if (string != 0) {
	int cmp2 = string_to_char(&string);
#ifdef USE_WIDE_CURSES
	wint_t cmp1 = dlg_toupper(ch);
	if (cmp2 != 0 && (wchar_t) cmp1 == (wchar_t) dlg_toupper(cmp2)) {
	    return TRUE;
	}
#else
	if (ch > 0 && ch < 256) {
	    if (dlg_toupper(ch) == dlg_toupper(cmp2))
		return TRUE;
	}
#endif
    }
    return FALSE;
}
Example #9
0
/* TODO : split this function in two so it becomes smaller */
SIGNATURE *signature_from_string(SSH_SESSION *session, STRING *signature,PUBLIC_KEY *pubkey,int needed_type){
#ifdef HAVE_LIBGCRYPT
    gcry_sexp_t sig;
#elif defined HAVE_LIBCRYPTO
    DSA_SIG *sig;
    STRING *r,*s;
#endif
    SIGNATURE *sign=malloc(sizeof(SIGNATURE));
    BUFFER *tmpbuf=buffer_new();
    STRING *rs;
    STRING *type_s,*e;
    int len,rsalen;
    char *type;
    buffer_add_data(tmpbuf,signature->string,string_len(signature));
    type_s=buffer_get_ssh_string(tmpbuf);
    if(!type_s){
        ssh_set_error(session,SSH_FATAL,"Invalid signature packet");
        buffer_free(tmpbuf);
        return NULL;
    }
    type=string_to_char(type_s);
    free(type_s);
    switch(needed_type){
        case TYPE_DSS:
            if(strcmp(type,"ssh-dss")){
                ssh_set_error(session,SSH_FATAL,"Invalid signature type : %s",type);
                buffer_free(tmpbuf);
                free(type);
                return NULL;
            }
            break;
        case TYPE_RSA:
            if(strcmp(type,"ssh-rsa")){
                ssh_set_error(session,SSH_FATAL,"Invalid signature type : %s",type);
                buffer_free(tmpbuf);
                free(type);
                return NULL;
            }
            break;
        default:
            ssh_set_error(session,SSH_FATAL,"Invalid signature type : %s",type);
            free(type);
            buffer_free(tmpbuf);
            return NULL;
    }
    free(type);
    switch(needed_type){
        case TYPE_DSS:
            rs=buffer_get_ssh_string(tmpbuf);
            buffer_free(tmpbuf);
            if(!rs || string_len(rs)!=40){ /* 40 is the dual signature blob len. */
                if(rs)
                    free(rs);
                return NULL;
            }
            /* we make use of strings (because we have all-made functions to convert them to bignums (ou pas ;)*/
#ifdef HAVE_LIBGCRYPT
            gcry_sexp_build(&sig,NULL,"(sig-val(dsa(r %b)(s %b)))",20,rs->string,20,rs->string+20);
#elif defined HAVE_LIBCRYPTO
            r=string_new(20);
            s=string_new(20);
            string_fill(r,rs->string,20);
            string_fill(s,rs->string+20,20);
            sig=DSA_SIG_new();
            sig->r=make_string_bn(r); /* is that really portable ? Openssh's hack isn't better */
            sig->s=make_string_bn(s);
            free(r);
            free(s);
#endif
#ifdef DEBUG_CRYPTO
            ssh_print_hexa("r",rs->string,20);
            ssh_print_hexa("s",rs->string+20,20);
#endif
            free(rs);
            sign->type=TYPE_DSS;
            sign->dsa_sign=sig;
            return sign;
        case TYPE_RSA:
            e=buffer_get_ssh_string(tmpbuf);
            buffer_free(tmpbuf);
            if(!e){
                return NULL;
            }
            len=string_len(e);
#ifdef HAVE_LIBGCRYPT
            rsalen=(gcry_pk_get_nbits(pubkey->rsa_pub)+7)/8;
#elif defined HAVE_LIBCRYPTO
            rsalen=RSA_size(pubkey->rsa_pub);
#endif
            if(len>rsalen){
                free(e);
                free(sign);
                ssh_set_error(session,SSH_FATAL,"signature too big ! %d instead of %d",len,rsalen);
                return NULL;
            }
            if(len<rsalen)
                ssh_log(session,SSH_LOG_RARE,"RSA signature len %d < %d",len,rsalen);
            sign->type=TYPE_RSA;
#ifdef HAVE_LIBGCRYPT
            gcry_sexp_build(&sig,NULL,"(sig-val(rsa(s %b)))",string_len(e),e->string);
            sign->rsa_sign=sig;
#elif defined HAVE_LIBCRYPTO
            sign->rsa_sign=e;
#endif
#ifdef DEBUG_CRYPTO
            ssh_say(0,"Len : %d\n",len);
            ssh_print_hexa("rsa signature",e->string,len);
#endif
#ifdef HAVE_LIBGCRYPT
            free(e);
#endif
            return sign;
        default:
            return NULL;
    }
}
Example #10
0
static int wait_auth_status(ssh_session session, int kbdint) {
  char *auth_methods = NULL;
  ssh_string auth;
  int rc = SSH_AUTH_ERROR;
  int cont = 1;
  uint8_t partial = 0;

  enter_function();

  while (cont) {
    if (packet_read(session) != SSH_OK) {
      break;
    }
    if (packet_translate(session) != SSH_OK) {
      break;
    }

    switch (session->in_packet.type) {
      case SSH2_MSG_USERAUTH_FAILURE:
        auth = buffer_get_ssh_string(session->in_buffer);
        if (auth == NULL || buffer_get_u8(session->in_buffer, &partial) != 1) {
          ssh_set_error(session, SSH_FATAL,
              "Invalid SSH_MSG_USERAUTH_FAILURE message");
          leave_function();
          return SSH_AUTH_ERROR;
        }

        auth_methods = string_to_char(auth);
        if (auth_methods == NULL) {
          ssh_set_error(session, SSH_FATAL,
              "Not enough space");
          string_free(auth);
          leave_function();
          return SSH_AUTH_ERROR;
        }

        if (partial) {
          rc = SSH_AUTH_PARTIAL;
          ssh_set_error(session, SSH_NO_ERROR,
              "Partial success. Authentication that can continue: %s",
              auth_methods);
        } else {
          rc = SSH_AUTH_DENIED;
          ssh_set_error(session, SSH_REQUEST_DENIED,
              "Access denied. Authentication that can continue: %s",
              auth_methods);

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

        string_free(auth);
        SAFE_FREE(auth_methods);
        cont = 0;
        break;
      case SSH2_MSG_USERAUTH_PK_OK:
        /* SSH monkeys have defined the same number for both */
        /* SSH_MSG_USERAUTH_PK_OK and SSH_MSG_USERAUTH_INFO_REQUEST */
        /* which is not really smart; */
        /*case SSH2_MSG_USERAUTH_INFO_REQUEST: */
        if (kbdint) {
          rc = SSH_AUTH_INFO;
          cont = 0;
          break;
        }
        /* continue through success */
      case SSH2_MSG_USERAUTH_SUCCESS:
        rc = SSH_AUTH_SUCCESS;
        cont = 0;
        break;
      case SSH2_MSG_USERAUTH_BANNER:
        {
          ssh_string banner;

          banner = buffer_get_ssh_string(session->in_buffer);
          if (banner == NULL) {
            ssh_log(session, SSH_LOG_PACKET,
                "The banner message was invalid. Continuing though\n");
            break;
          }
          ssh_log(session, SSH_LOG_PACKET,
              "Received a message banner\n");
          string_free(session->banner); /* erase the older one */
          session->banner = banner;
          break;
        }
      default:
        packet_parse(session);
        break;
    }
  }

  leave_function();
  return rc;
}
Example #11
0
int ssh_get_kex(SSH_SESSION *session, int server_kex) {
  STRING *str = NULL;
  char *strings[10];
  int i;

  enter_function();

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

  if (buffer_get_data(session->in_buffer,session->server_kex.cookie,16) != 16) {
    ssh_set_error(session, SSH_FATAL, "get_kex(): no cookie in packet");
    leave_function();
    return -1;
  }

  if (hashbufin_add_cookie(session, session->server_kex.cookie) < 0) {
    ssh_set_error(session, SSH_FATAL, "get_kex(): adding cookie failed");
    leave_function();
    return -1;
  }

  memset(strings, 0, sizeof(char *) * 10);

  for (i = 0; i < 10; i++) {
    str = buffer_get_ssh_string(session->in_buffer);
    if (str == NULL) {
      break;
    }

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

    strings[i] = string_to_char(str);
    if (strings[i] == NULL) {
      goto error;
    }
    string_free(str);
    str = NULL;
  }

  /* copy the server kex info into an array of strings */
  if (server_kex) {
    session->client_kex.methods = malloc(10 * sizeof(char **));
    if (session->client_kex.methods == NULL) {
      leave_function();
      return -1;
    }

    for (i = 0; i < 10; i++) {
      session->client_kex.methods[i] = strings[i];
    }
  } else { /* client */
    session->server_kex.methods = malloc(10 * sizeof(char **));
    if (session->server_kex.methods == NULL) {
      leave_function();
      return -1;
    }

    for (i = 0; i < 10; i++) {
      session->server_kex.methods[i] = strings[i];
    }
  }

  leave_function();
  return 0;
error:
  string_free(str);
  for (i = 0; i < 10; i++) {
    SAFE_FREE(strings[i]);
  }

  leave_function();
  return -1;
}
Example #12
0
static void channel_rcv_request(SSH_SESSION *session) {
  CHANNEL *channel;
  STRING *request_s;
  char *request;
  u32 status;

  enter_function();

  channel = channel_from_msg(session);
  if (channel == NULL) {
    ssh_log(session, SSH_LOG_FUNCTIONS, ssh_get_error(session));
    leave_function();
    return;
  }

  request_s = buffer_get_ssh_string(session->in_buffer);
  if (request_s == NULL) {
    ssh_log(session, SSH_LOG_PACKET, "Invalid MSG_CHANNEL_REQUEST");
    leave_function();
    return;
  }

  request = string_to_char(request_s);
  string_free(request_s);
  if (request == NULL) {
    leave_function();
    return;
  }

  buffer_get_u8(session->in_buffer, (u8 *) &status);

  if (strcmp(request,"exit-status") == 0) {
    SAFE_FREE(request);
    ssh_log(session, SSH_LOG_PACKET, "received exit-status");
    buffer_get_u32(session->in_buffer, &status);
    channel->exit_status = ntohl(status);

    leave_function();
    return ;
  }

  if (strcmp(request, "exit-signal") == 0) {
    const char *core = "(core dumped)";
    STRING *signal_s;
    char *signal;
    u8 i;

    SAFE_FREE(request);

    signal_s = buffer_get_ssh_string(session->in_buffer);
    if (signal_s == NULL) {
      ssh_log(session, SSH_LOG_PACKET, "Invalid MSG_CHANNEL_REQUEST");
      leave_function();
      return;
    }

    signal = string_to_char(signal_s);
    string_free(signal_s);
    if (signal == NULL) {
      leave_function();
      return;
    }

    buffer_get_u8(session->in_buffer, &i);
    if (i == 0) {
      core = "";
    }

    ssh_log(session, SSH_LOG_PACKET,
        "Remote connection closed by signal SIG %s %s", signal, core);
    SAFE_FREE(signal);

    leave_function();
    return;
  }
  ssh_log(session, SSH_LOG_PACKET, "Unknown request %s", request);
  SAFE_FREE(request);

  leave_function();
}
Example #13
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;
}
Example #14
0
static int wait_auth_status(SSH_SESSION *session,int kbdint){
    int err=SSH_AUTH_ERROR;
    int cont=1;
    STRING *auth;
    u8 partial=0;
    int todo = 0;
    char *auth_methods = NULL;
    enter_function();
    while(cont){
        if(packet_read(session))
            break;
        if(packet_translate(session))
            break;
        switch(session->in_packet.type){
            case SSH2_MSG_USERAUTH_FAILURE:
                auth = buffer_get_ssh_string(session->in_buffer);
                if(!auth || buffer_get_u8(session->in_buffer,&partial)!=1 ){
                    ssh_set_error(session,SSH_FATAL,
                            "invalid SSH_MSG_USERAUTH_FAILURE message");
                    leave_function();
                    return SSH_AUTH_ERROR;
                }
                auth_methods = string_to_char(auth);
                if(partial) {
                    err=SSH_AUTH_PARTIAL;
                    ssh_set_error(session,SSH_NO_ERROR,"partial success, authentications that can continue : %s", auth_methods);
                } else {
                    err=SSH_AUTH_DENIED;
                    ssh_set_error(session,SSH_REQUEST_DENIED,"Access denied. authentications that can continue : %s", auth_methods);

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


                free(auth);
                free(auth_methods);
                cont=0;
                break;
            case SSH2_MSG_USERAUTH_PK_OK:
                /* SSH monkeys have defined the same number for both */
                /* SSH_MSG_USERAUTH_PK_OK and SSH_MSG_USERAUTH_INFO_REQUEST */
                /* which is not really smart; */
          /*case SSH2_MSG_USERAUTH_INFO_REQUEST: */
                if(kbdint){
                    err=SSH_AUTH_INFO;
                    cont=0;
                    break;
                }
                /* continue through success */
            case SSH2_MSG_USERAUTH_SUCCESS:
                err=SSH_AUTH_SUCCESS;
                cont=0;
                break;
            case SSH2_MSG_USERAUTH_BANNER:
                {
                    STRING *banner=buffer_get_ssh_string(session->in_buffer);
                    if(!banner){
                        ssh_say(1,"The banner message was invalid. continuing though\n");
                        break;
                    }
                    ssh_say(2,"Received a message banner\n");
                    if(session->banner)
                        free(session->banner); /* erase the older one */
                    session->banner=banner;
                    break;
                }
            default:
                packet_parse(session);
                break;
        }
    }
    leave_function();
    return err;
}
Example #15
0
/** this is the banner showing a disclaimer to users who log in,
 * typicaly their right or the fact that they will be monitored
 * \brief get the issue banner from the server
 * \param session ssh session
 * \return NULL if there is no issue banner, else a string containing it.
 */
char *ssh_get_issue_banner(SSH_SESSION *session){
    if(!session->banner)
        return NULL;
    return string_to_char(session->banner);
}
Example #16
0
/* TODO : split this function in two so it becomes smaller */
SIGNATURE *signature_from_string(ssh_session session, ssh_string signature,
    ssh_public_key pubkey, int needed_type) {
  SIGNATURE *sign = NULL;
  ssh_buffer tmpbuf = NULL;
  ssh_string rs = NULL;
  ssh_string type_s = NULL;
  ssh_string e = NULL;
  char *type_c = NULL;
  int type;
  int len;
  int rsalen;
#ifdef HAVE_LIBGCRYPT
  gcry_sexp_t sig;
#elif defined HAVE_LIBCRYPTO
  DSA_SIG *sig = NULL;
  ssh_string r = NULL;
  ssh_string s = NULL;
#endif

  sign = malloc(sizeof(SIGNATURE));
  if (sign == NULL) {
    ssh_set_error(session, SSH_FATAL, "Not enough space");
    return NULL;
  }

  tmpbuf = buffer_new();
  if (tmpbuf == NULL) {
    ssh_set_error(session, SSH_FATAL, "Not enough space");
    signature_free(sign);
    return NULL;
  }

  if (buffer_add_data(tmpbuf, string_data(signature), string_len(signature)) < 0) {
    signature_free(sign);
    buffer_free(tmpbuf);
    return NULL;
  }

  type_s = buffer_get_ssh_string(tmpbuf);
  if (type_s == NULL) {
    ssh_set_error(session, SSH_FATAL, "Invalid signature packet");
    signature_free(sign);
    buffer_free(tmpbuf);
    return NULL;
  }

  type_c = string_to_char(type_s);
  string_free(type_s);
  if (type_c == NULL) {
    signature_free(sign);
    buffer_free(tmpbuf);
    return NULL;
  }
  type = ssh_type_from_name(type_c);
  SAFE_FREE(type_c);

  if (needed_type != type) {
    ssh_set_error(session, SSH_FATAL, "Invalid signature type: %s",
        ssh_type_to_char(type));
    signature_free(sign);
    buffer_free(tmpbuf);
    return NULL;
  }

  switch(needed_type) {
    case TYPE_DSS:
      rs = buffer_get_ssh_string(tmpbuf);
      buffer_free(tmpbuf);

      /* 40 is the dual signature blob len. */
      if (rs == NULL || string_len(rs) != 40) {
        string_free(rs);
        signature_free(sign);
        return NULL;
      }

      /* we make use of strings (because we have all-made functions to convert
       * them to bignums (ou pas ;) */
#ifdef HAVE_LIBGCRYPT
      if (gcry_sexp_build(&sig, NULL, "(sig-val(dsa(r %b)(s %b)))",
            20 ,string_data(rs), 20,(unsigned char *)string_data(rs) + 20)) {
        string_free(rs);
        signature_free(sign);
        return NULL;
      }
#elif defined HAVE_LIBCRYPTO
      r = string_new(20);
      s = string_new(20);
      if (r == NULL || s == NULL) {
        string_free(r);
        string_free(s);
        string_free(rs);
        signature_free(sign);
        return NULL;
      }

      string_fill(r, string_data(rs), 20);
      string_fill(s, (char *)string_data(rs) + 20, 20);

      sig = DSA_SIG_new();
      if (sig == NULL) {
        string_free(r);
        string_free(s);
        string_free(rs);
        signature_free(sign);
        return NULL;
      }
      sig->r = make_string_bn(r); /* is that really portable ? Openssh's hack isn't better */
      sig->s = make_string_bn(s);
      string_free(r);
      string_free(s);

      if (sig->r == NULL || sig->s == NULL) {
        string_free(rs);
        DSA_SIG_free(sig);
        signature_free(sign);
        return NULL;
      }
#endif

#ifdef DEBUG_CRYPTO
      ssh_print_hexa("r", string_data(rs), 20);
      ssh_print_hexa("s", (const unsigned char *)string_data(rs) + 20, 20);
#endif
      string_free(rs);

      sign->type = TYPE_DSS;
      sign->dsa_sign = sig;

      return sign;
    case TYPE_RSA:
      e = buffer_get_ssh_string(tmpbuf);
      buffer_free(tmpbuf);
      if (e == NULL) {
        signature_free(sign);
        return NULL;
      }
      len = string_len(e);
#ifdef HAVE_LIBGCRYPT
      rsalen = (gcry_pk_get_nbits(pubkey->rsa_pub) + 7) / 8;
#elif defined HAVE_LIBCRYPTO
      rsalen = RSA_size(pubkey->rsa_pub);
#endif
      if (len > rsalen) {
        string_free(e);
        signature_free(sign);
        ssh_set_error(session, SSH_FATAL, "Signature too big! %d instead of %d",
            len, rsalen);
        return NULL;
      }

      if (len < rsalen) {
        ssh_log(session, SSH_LOG_RARE, "RSA signature len %d < %d",
            len, rsalen);
      }
      sign->type = TYPE_RSA;
#ifdef HAVE_LIBGCRYPT
      if (gcry_sexp_build(&sig, NULL, "(sig-val(rsa(s %b)))",
          string_len(e), string_data(e))) {
        signature_free(sign);
        string_free(e);
        return NULL;
      }

      sign->rsa_sign = sig;
#elif defined HAVE_LIBCRYPTO
      sign->rsa_sign = e;
#endif

#ifdef DEBUG_CRYPTO
      ssh_log(session, SSH_LOG_FUNCTIONS, "len e: %d", len);
      ssh_print_hexa("RSA signature", string_data(e), len);
#endif

#ifdef HAVE_LIBGCRYPT
      string_free(e);
#endif

      return sign;
    default:
      return NULL;
  }

  return NULL;
}
Example #17
0
static int kbdauth_info_get(ssh_session session) {
  ssh_string name; /* name of the "asking" window showed to client */
  ssh_string instruction;
  ssh_string tmp;
  uint32_t nprompts;
  uint32_t i;

  enter_function();

  name = buffer_get_ssh_string(session->in_buffer);
  instruction = buffer_get_ssh_string(session->in_buffer);
  tmp = buffer_get_ssh_string(session->in_buffer);
  buffer_get_u32(session->in_buffer, &nprompts);

  if (name == NULL || instruction == NULL || tmp == NULL) {
    string_free(name);
    string_free(instruction);
    /* tmp if empty if we got here */
    ssh_set_error(session, SSH_FATAL, "Invalid USERAUTH_INFO_REQUEST msg");
    leave_function();
    return SSH_AUTH_ERROR;
  }
  string_free(tmp);

  if (session->kbdint == NULL) {
    session->kbdint = kbdint_new();
    if (session->kbdint == NULL) {
      ssh_set_error(session, SSH_FATAL, "Not enough space");
      string_free(name);
      string_free(instruction);

      leave_function();
      return SSH_AUTH_ERROR;
    }
  } else {
    kbdint_clean(session->kbdint);
  }

  session->kbdint->name = string_to_char(name);
  string_free(name);
  if (session->kbdint->name == NULL) {
    ssh_set_error(session, SSH_FATAL, "Not enough space");
    kbdint_free(session->kbdint);
    leave_function();
    return SSH_AUTH_ERROR;
  }

  session->kbdint->instruction = string_to_char(instruction);
  string_free(instruction);
  if (session->kbdint->instruction == NULL) {
    ssh_set_error(session, SSH_FATAL, "Not enough space");
    kbdint_free(session->kbdint);
    session->kbdint = NULL;
    leave_function();
    return SSH_AUTH_ERROR;
  }

  nprompts = ntohl(nprompts);
  if (nprompts > KBDINT_MAX_PROMPT) {
    ssh_set_error(session, SSH_FATAL,
        "Too much prompt asked from server: %u (0x%.4x)",
        nprompts, nprompts);
    kbdint_free(session->kbdint);
    session->kbdint = NULL;
    leave_function();
    return SSH_AUTH_ERROR;
  }

  session->kbdint->nprompts = nprompts;
  session->kbdint->prompts = malloc(nprompts * sizeof(char *));
  if (session->kbdint->prompts == NULL) {
    session->kbdint->nprompts = 0;
    ssh_set_error(session, SSH_FATAL, "No space left");
    kbdint_free(session->kbdint);
    session->kbdint = NULL;
    leave_function();
    return SSH_AUTH_ERROR;
  }
  memset(session->kbdint->prompts, 0, nprompts * sizeof(char *));

  session->kbdint->echo = malloc(nprompts);
  if (session->kbdint->echo == NULL) {
    session->kbdint->nprompts = 0;
    ssh_set_error(session, SSH_FATAL, "No space left");
    kbdint_free(session->kbdint);
    session->kbdint = NULL;
    leave_function();
    return SSH_AUTH_ERROR;
  }
  memset(session->kbdint->echo, 0, nprompts);

  for (i = 0; i < nprompts; i++) {
    tmp = buffer_get_ssh_string(session->in_buffer);
    buffer_get_u8(session->in_buffer, &session->kbdint->echo[i]);
    if (tmp == NULL) {
      ssh_set_error(session, SSH_FATAL, "Short INFO_REQUEST packet");
      kbdint_free(session->kbdint);
      session->kbdint = NULL;
      leave_function();
      return SSH_AUTH_ERROR;
    }
    session->kbdint->prompts[i] = string_to_char(tmp);
    string_free(tmp);
    if (session->kbdint->prompts[i] == NULL) {
      ssh_set_error(session, SSH_FATAL, "Not enough space");
      kbdint_free(session->kbdint);
      session->kbdint = NULL;
      leave_function();
      return SSH_AUTH_ERROR;
    }
  }

  leave_function();
  return SSH_AUTH_INFO; /* we are not auth. but we parsed the packet */
}
void PhysXForceField::setName(const core::string& name)
{
	m_name=name;
	m_forceField->setName(string_to_char(name).c_str());
}
Example #19
0
SFTP_CLIENT_MESSAGE *sftp_get_client_message(SFTP_SESSION *sftp) {
    SFTP_PACKET *packet=sftp_packet_read(sftp);
    SFTP_CLIENT_MESSAGE *msg=malloc(sizeof (SFTP_CLIENT_MESSAGE));
    BUFFER *payload;
    STRING *tmp;
    memset(msg,0,sizeof(SFTP_CLIENT_MESSAGE));
    if(!packet)
        return NULL;
    payload=packet->payload;
    ssh_say(2,"received sftp packet type %d\n",packet->type);
    msg->type=packet->type;
    msg->sftp=sftp;
    buffer_get_u32(payload,&msg->id);
    switch(msg->type) {
    case SSH_FXP_CLOSE:
    case SSH_FXP_READDIR:
        msg->handle=buffer_get_ssh_string(payload);
        break;
    case SSH_FXP_READ:
        msg->handle=buffer_get_ssh_string(payload);
        buffer_get_u64(payload,&msg->offset);
        buffer_get_u32(payload,&msg->len);
        break;
    case SSH_FXP_WRITE:
        msg->handle=buffer_get_ssh_string(payload);
        buffer_get_u64(payload,&msg->offset);
        msg->data=buffer_get_ssh_string(payload);
        break;
    case SSH_FXP_REMOVE:
    case SSH_FXP_RMDIR:
    case SSH_FXP_OPENDIR:
    case SSH_FXP_READLINK:
    case SSH_FXP_REALPATH:
        tmp=buffer_get_ssh_string(payload);
        msg->filename=string_to_char(tmp);
        free(tmp);
        break;
    case SSH_FXP_RENAME:
    case SSH_FXP_SYMLINK:
        tmp=buffer_get_ssh_string(payload);
        msg->filename=string_to_char(tmp);
        free(tmp);
        msg->data=buffer_get_ssh_string(payload);
        break;
    case SSH_FXP_MKDIR:
    case SSH_FXP_SETSTAT:
        tmp=buffer_get_ssh_string(payload);
        msg->filename=string_to_char(tmp);
        free(tmp);
        msg->attr=sftp_parse_attr(sftp, payload,0);
        break;
    case SSH_FXP_FSETSTAT:
        msg->handle=buffer_get_ssh_string(payload);
        msg->attr=sftp_parse_attr(sftp, payload,0);
        break;
    case SSH_FXP_LSTAT:
    case SSH_FXP_STAT:
        tmp=buffer_get_ssh_string(payload);
        msg->filename=string_to_char(tmp);
        free(tmp);
        if(sftp->version >3)
            buffer_get_u32(payload,&msg->flags);
        break;
    case SSH_FXP_OPEN:
        tmp=buffer_get_ssh_string(payload);
        msg->filename=string_to_char(tmp);
        free(tmp);
        buffer_get_u32(payload,&msg->flags);
        msg->attr=sftp_parse_attr(sftp, payload,0);
    case SSH_FXP_FSTAT:
        msg->handle=buffer_get_ssh_string(payload);
        buffer_get_u32(payload,&msg->flags);
        break;
    default:
        printf("Received handled sftp message %d\n",msg->type);
    }
    msg->flags=ntohl(msg->flags);
    msg->offset=ntohll(msg->offset);
    msg->len=ntohl(msg->len);
    sftp_packet_free(packet);
    return msg;
}
Example #20
0
void packet_parse(SSH_SESSION *session) {
  STRING *error_s = NULL;
  char *error = NULL;
  int type = session->in_packet.type;
  u32 tmp;

#ifdef HAVE_SSH1
  if (session->version == 1) {
    /* SSH-1 */
    switch(type) {
      case SSH_MSG_DISCONNECT:
        ssh_log(session, SSH_LOG_PACKET, "Received SSH_MSG_DISCONNECT");
        ssh_set_error(session, SSH_FATAL, "Received SSH_MSG_DISCONNECT");

        ssh_socket_close(session->socket);
        session->alive = 0;
        return;
      case SSH_SMSG_STDOUT_DATA:
      case SSH_SMSG_STDERR_DATA:
      case SSH_SMSG_EXITSTATUS:
        channel_handle1(session,type);
        return;
      case SSH_MSG_DEBUG:
      case SSH_MSG_IGNORE:
        break;
      default:
        ssh_log(session, SSH_LOG_PACKET,
            "Unexpected message code %d", type);
    }
    return;
  } else {
#endif /* HAVE_SSH1 */
    switch(type) {
      case SSH2_MSG_DISCONNECT:
        buffer_get_u32(session->in_buffer, &tmp);
        error_s = buffer_get_ssh_string(session->in_buffer);
        if (error_s == NULL) {
          return;
        }
        error = string_to_char(error_s);
        string_free(error_s);
        if (error == NULL) {
          return;
        }
        ssh_log(session, SSH_LOG_PACKET, "Received SSH_MSG_DISCONNECT\n");
        ssh_set_error(session, SSH_FATAL,
            "Received SSH_MSG_DISCONNECT: %s",error);

        SAFE_FREE(error);

        ssh_socket_close(session->socket);
        session->alive = 0;

        return;
      case SSH2_MSG_CHANNEL_WINDOW_ADJUST:
      case SSH2_MSG_CHANNEL_DATA:
      case SSH2_MSG_CHANNEL_EXTENDED_DATA:
      case SSH2_MSG_CHANNEL_REQUEST:
      case SSH2_MSG_CHANNEL_EOF:
      case SSH2_MSG_CHANNEL_CLOSE:
        channel_handle(session,type);
      case SSH2_MSG_IGNORE:
      case SSH2_MSG_DEBUG:
        return;
      default:
        ssh_log(session, SSH_LOG_RARE, "Received unhandled packet %d", type);
    }
#ifdef HAVE_SSH1
  }
#endif
}