Esempio n. 1
0
/**
 * @brief Get the issue banner from the server.
 *
 * This is the banner showing a disclaimer to users who log in,
 * typically their right or the fact that they will be monitored.
 *
 * @param[in]  session  The SSH session to use.
 *
 * @return A newly allocated string with the banner, NULL on error.
 */
char *ssh_get_issue_banner(ssh_session session) {
  if (session == NULL || session->banner == NULL) {
    return NULL;
  }

  return ssh_string_to_char(session->banner);
}
Esempio n. 2
0
/* caller has to free commment */
ssh_key ssh_agent_get_next_ident(struct ssh_session_struct *session,
    char **comment) {
    struct ssh_key_struct *key;
    struct ssh_string_struct *blob = NULL;
    struct ssh_string_struct *tmp = NULL;
    int rc;

    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) {
                ssh_string_free(blob);

                return NULL;
            }

            if (comment) {
                *comment = ssh_string_to_char(tmp);
            } else {
                ssh_string_free(blob);
                ssh_string_free(tmp);

                return NULL;
            }
            ssh_string_free(tmp);

            /* get key from blob */
            rc = ssh_pki_import_pubkey_blob(blob, &key);
            ssh_string_free(blob);
            if (rc == SSH_ERROR) {
                return NULL;
            }
            break;
        default:
            return NULL;
    }

    return key;
}
Esempio n. 3
0
File: keys.c Progetto: rofl0r/libssh
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 = ssh_buffer_new();
    if (tmpbuf == NULL) {
        return NULL;
    }

    if (buffer_add_data(tmpbuf, ssh_string_data(pubkey_s), ssh_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 = ssh_string_to_char(type_s);
    ssh_string_free(type_s);
    if (type_c == NULL) {
        goto error;
    }

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

    switch (type) {
    case SSH_KEYTYPE_DSS:
        return publickey_make_dss(session, tmpbuf);
    case SSH_KEYTYPE_RSA:
    case SSH_KEYTYPE_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:
    ssh_buffer_free(tmpbuf);
    return NULL;
}
Esempio n. 4
0
File: keys.c Progetto: rofl0r/libssh
/* 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;
    }
    ZERO_STRUCTP(sign);

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

    if (buffer_add_data(tmpbuf, ssh_string_data(signature), ssh_string_len(signature)) < 0) {
        signature_free(sign);
        ssh_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);
        ssh_buffer_free(tmpbuf);
        return NULL;
    }

    type_c = ssh_string_to_char(type_s);
    ssh_string_free(type_s);
    if (type_c == NULL) {
        signature_free(sign);
        ssh_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);
        ssh_buffer_free(tmpbuf);
        return NULL;
    }

    switch(needed_type) {
    case SSH_KEYTYPE_DSS:
        rs = buffer_get_ssh_string(tmpbuf);
        ssh_buffer_free(tmpbuf);

        /* 40 is the dual signature blob len. */
        if (rs == NULL || ssh_string_len(rs) != 40) {
            ssh_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 ,ssh_string_data(rs), 20,(unsigned char *)ssh_string_data(rs) + 20)) {
            ssh_string_free(rs);
            signature_free(sign);
            return NULL;
        }
#elif defined HAVE_LIBCRYPTO
        r = ssh_string_new(20);
        s = ssh_string_new(20);
        if (r == NULL || s == NULL) {
            ssh_string_free(r);
            ssh_string_free(s);
            ssh_string_free(rs);
            signature_free(sign);
            return NULL;
        }

        ssh_string_fill(r, ssh_string_data(rs), 20);
        ssh_string_fill(s, (char *)ssh_string_data(rs) + 20, 20);

        sig = DSA_SIG_new();
        if (sig == NULL) {
            ssh_string_free(r);
            ssh_string_free(s);
            ssh_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);
        ssh_string_free(r);
        ssh_string_free(s);

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

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

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

        return sign;
    case SSH_KEYTYPE_RSA:
        e = buffer_get_ssh_string(tmpbuf);
        ssh_buffer_free(tmpbuf);
        if (e == NULL) {
            signature_free(sign);
            return NULL;
        }
        len = ssh_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) {
            ssh_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 = SSH_KEYTYPE_RSA;
#ifdef HAVE_LIBGCRYPT
        if (gcry_sexp_build(&sig, NULL, "(sig-val(rsa(s %b)))",
                            ssh_string_len(e), ssh_string_data(e))) {
            signature_free(sign);
            ssh_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", ssh_string_data(e), len);
#endif

#ifdef HAVE_LIBGCRYPT
        ssh_string_free(e);
#endif

        return sign;
    default:
        return NULL;
    }

    return NULL;
}
Esempio n. 5
0
/**
 * @internal
 *
 * @brief This function parses the last end of a channel request packet.
 *
 * This is normally converted to a SSH message and placed in the queue.
 *
 * @param[in]  session  The SSH session.
 *
 * @param[in]  channel  The channel the request is made on.
 *
 * @param[in]  packet   The rest of the packet to be parsed.
 *
 * @param[in]  request  The type of request.
 *
 * @param[in]  want_reply The want_reply field from the request.
 *
 * @returns             SSH_OK on success, SSH_ERROR if an error occured.
 */
int ssh_message_handle_channel_request(ssh_session session, ssh_channel channel, ssh_buffer packet,
    const char *request, uint8_t want_reply) {
  ssh_message msg = NULL;
  enter_function();
  msg = ssh_message_new(session);
  if (msg == NULL) {
    ssh_set_error_oom(session);
    goto error;
  }

  ssh_log(session, SSH_LOG_PACKET,
      "Received a %s channel_request for channel (%d:%d) (want_reply=%hhd)",
      request, channel->local_channel, channel->remote_channel, want_reply);

  msg->type = SSH_REQUEST_CHANNEL;
  msg->channel_request.channel = channel;
  msg->channel_request.want_reply = want_reply;

  if (strcmp(request, "pty-req") == 0) {
    ssh_string term = NULL;
    char *term_c = NULL;
    term = buffer_get_ssh_string(packet);
    if (term == NULL) {
      ssh_set_error_oom(session);
      goto error;
    }
    term_c = ssh_string_to_char(term);
    if (term_c == NULL) {
      ssh_set_error_oom(session);
      ssh_string_free(term);
      goto error;
    }
    ssh_string_free(term);

    msg->channel_request.type = SSH_CHANNEL_REQUEST_PTY;
    msg->channel_request.TERM = term_c;

    buffer_get_u32(packet, &msg->channel_request.width);
    buffer_get_u32(packet, &msg->channel_request.height);
    buffer_get_u32(packet, &msg->channel_request.pxwidth);
    buffer_get_u32(packet, &msg->channel_request.pxheight);

    msg->channel_request.width = ntohl(msg->channel_request.width);
    msg->channel_request.height = ntohl(msg->channel_request.height);
    msg->channel_request.pxwidth = ntohl(msg->channel_request.pxwidth);
    msg->channel_request.pxheight = ntohl(msg->channel_request.pxheight);
    msg->channel_request.modes = buffer_get_ssh_string(packet);
    if (msg->channel_request.modes == NULL) {
      SAFE_FREE(term_c);
      goto error;
    }
    goto end;
  }

  if (strcmp(request, "window-change") == 0) {
    msg->channel_request.type = SSH_CHANNEL_REQUEST_WINDOW_CHANGE;

    buffer_get_u32(packet, &msg->channel_request.width);
    buffer_get_u32(packet, &msg->channel_request.height);
    buffer_get_u32(packet, &msg->channel_request.pxwidth);
    buffer_get_u32(packet, &msg->channel_request.pxheight);

    msg->channel_request.width = ntohl(msg->channel_request.width);
    msg->channel_request.height = ntohl(msg->channel_request.height);
    msg->channel_request.pxwidth = ntohl(msg->channel_request.pxwidth);
    msg->channel_request.pxheight = ntohl(msg->channel_request.pxheight);

    goto end;
  }

  if (strcmp(request, "subsystem") == 0) {
    ssh_string subsys = NULL;
    char *subsys_c = NULL;
    subsys = buffer_get_ssh_string(packet);
    if (subsys == NULL) {
      ssh_set_error_oom(session);
      goto error;
    }
    subsys_c = ssh_string_to_char(subsys);
    if (subsys_c == NULL) {
      ssh_set_error_oom(session);
      ssh_string_free(subsys);
      goto error;
    }
    ssh_string_free(subsys);

    msg->channel_request.type = SSH_CHANNEL_REQUEST_SUBSYSTEM;
    msg->channel_request.subsystem = subsys_c;

    goto end;
  }

  if (strcmp(request, "shell") == 0) {
    msg->channel_request.type = SSH_CHANNEL_REQUEST_SHELL;
    goto end;
  }

  if (strcmp(request, "exec") == 0) {
    ssh_string cmd = NULL;
    cmd = buffer_get_ssh_string(packet);
    if (cmd == NULL) {
      ssh_set_error_oom(session);
      goto error;
    }
    msg->channel_request.type = SSH_CHANNEL_REQUEST_EXEC;
    msg->channel_request.command = ssh_string_to_char(cmd);
    ssh_string_free(cmd);
    if (msg->channel_request.command == NULL) {
      goto error;
    }
    goto end;
  }

  if (strcmp(request, "env") == 0) {
    ssh_string name = NULL;
    ssh_string value = NULL;
    name = buffer_get_ssh_string(packet);
    if (name == NULL) {
      ssh_set_error_oom(session);
      goto error;
    }
    value = buffer_get_ssh_string(packet);
    if (value == NULL) {
      ssh_set_error_oom(session);
      ssh_string_free(name);
      goto error;
    }

    msg->channel_request.type = SSH_CHANNEL_REQUEST_ENV;
    msg->channel_request.var_name = ssh_string_to_char(name);
    msg->channel_request.var_value = ssh_string_to_char(value);
    if (msg->channel_request.var_name == NULL ||
        msg->channel_request.var_value == NULL) {
      ssh_string_free(name);
      ssh_string_free(value);
      goto error;
    }
    ssh_string_free(name);
    ssh_string_free(value);

    goto end;
  }

  if (strcmp(request, "x11-req") == 0) {
    ssh_string auth_protocol = NULL;
    ssh_string auth_cookie = NULL;

    buffer_get_u8(packet, &msg->channel_request.x11_single_connection);

    auth_protocol = buffer_get_ssh_string(packet);
    if (auth_protocol == NULL) {
      ssh_set_error_oom(session);
      goto error;
    }
    auth_cookie = buffer_get_ssh_string(packet);
    if (auth_cookie == NULL) {
      ssh_set_error_oom(session);
      ssh_string_free(auth_protocol);
      goto error;
    }

    msg->channel_request.type = SSH_CHANNEL_REQUEST_X11;
    msg->channel_request.x11_auth_protocol = ssh_string_to_char(auth_protocol);
    msg->channel_request.x11_auth_cookie = ssh_string_to_char(auth_cookie);
    if (msg->channel_request.x11_auth_protocol == NULL ||
        msg->channel_request.x11_auth_cookie == NULL) {
      ssh_string_free(auth_protocol);
      ssh_string_free(auth_cookie);
      goto error;
    }
    ssh_string_free(auth_protocol);
    ssh_string_free(auth_cookie);

    buffer_get_u32(packet, &msg->channel_request.x11_screen_number);

    goto end;
  }

  msg->channel_request.type = SSH_CHANNEL_UNKNOWN;
end:
  ssh_message_queue(session,msg);
  leave_function();
  return SSH_OK;
error:
  ssh_message_free(msg);

  leave_function();
  return SSH_ERROR;
}
Esempio n. 6
0
const char *sftp_client_message_get_data(sftp_client_message msg){
	if (msg->str_data == NULL)
		msg->str_data = ssh_string_to_char(msg->data);
	return msg->str_data;
}
Esempio n. 7
0
char *string_to_char(ssh_string str){
  return ssh_string_to_char(str);
}