/** * \internal * \brief creates a new Socket object */ ssh_socket ssh_socket_new(ssh_session session) { ssh_socket s; s = malloc(sizeof(struct ssh_socket_struct)); if (s == NULL) { ssh_set_error_oom(session); return NULL; } s->fd_in = SSH_INVALID_SOCKET; s->fd_out= SSH_INVALID_SOCKET; s->last_errno = -1; s->fd_is_socket = 1; s->session = session; s->in_buffer = ssh_buffer_new(); if (s->in_buffer == NULL) { ssh_set_error_oom(session); SAFE_FREE(s); return NULL; } s->out_buffer=ssh_buffer_new(); if (s->out_buffer == NULL) { ssh_set_error_oom(session); ssh_buffer_free(s->in_buffer); SAFE_FREE(s); return NULL; } s->read_wontblock = 0; s->write_wontblock = 0; s->data_except = 0; s->poll_in=s->poll_out=NULL; s->state=SSH_SOCKET_NONE; return s; }
int sftp_reply_names(sftp_client_message msg) { ssh_buffer out; out = ssh_buffer_new(); if (out == NULL) { ssh_buffer_free(msg->attrbuf); return -1; } if (ssh_buffer_add_u32(out, msg->id) < 0 || ssh_buffer_add_u32(out, htonl(msg->attr_num)) < 0 || ssh_buffer_add_data(out, ssh_buffer_get(msg->attrbuf), ssh_buffer_get_len(msg->attrbuf)) < 0 || sftp_packet_write(msg->sftp, SSH_FXP_NAME, out) < 0) { ssh_buffer_free(out); ssh_buffer_free(msg->attrbuf); return -1; } ssh_buffer_free(out); ssh_buffer_free(msg->attrbuf); msg->attr_num = 0; msg->attrbuf = NULL; return 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; }
/** * @brief opens a new pcap file and create header */ int ssh_pcap_file_open(ssh_pcap_file pcap, const char *filename){ ssh_buffer header; int err; if(pcap == NULL) return SSH_ERROR; if(pcap->output){ fclose(pcap->output); pcap->output=NULL; } pcap->output=fopen(filename,"wb"); if(pcap->output==NULL) return SSH_ERROR; header=ssh_buffer_new(); if(header==NULL) return SSH_ERROR; buffer_add_u32(header,htonl(PCAP_MAGIC)); buffer_add_u16(header,htons(PCAP_VERSION_MAJOR)); buffer_add_u16(header,htons(PCAP_VERSION_MINOR)); /* currently hardcode GMT to 0 */ buffer_add_u32(header,htonl(0)); /* accuracy */ buffer_add_u32(header,htonl(0)); /* size of the biggest packet */ buffer_add_u32(header,htonl(MAX_PACKET_LEN)); /* we will write sort-of IP */ buffer_add_u32(header,htonl(DLT_RAW)); err=ssh_pcap_file_write(pcap,header); ssh_buffer_free(header); return err; }
/* 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; }
static ssh_buffer ssh_gssapi_build_mic(ssh_session session){ ssh_buffer mic_buffer; int rc; mic_buffer = ssh_buffer_new(); if (mic_buffer == NULL) { ssh_set_error_oom(session); return NULL; } rc = ssh_buffer_pack(mic_buffer, "dPbsss", session->current_crypto->digest_len, (size_t)session->current_crypto->digest_len, session->current_crypto->session_id, SSH2_MSG_USERAUTH_REQUEST, session->gssapi->user, "ssh-connection", "gssapi-with-mic"); if (rc != SSH_OK) { ssh_set_error_oom(session); ssh_buffer_free(mic_buffer); return NULL; } return mic_buffer; }
/** * @brief Copy the certificate part of a public key into a private key. * * @param[in] certkey The certificate key. * * @param[in] privkey The target private key to copy the certificate to. * * @returns SSH_OK on success, SSH_ERROR otherwise. **/ int ssh_pki_copy_cert_to_privkey(const ssh_key certkey, ssh_key privkey) { ssh_buffer cert_buffer; int rc; if (certkey == NULL || privkey == NULL) { return SSH_ERROR; } if (privkey->cert != NULL) { return SSH_ERROR; } if (certkey->cert == NULL) { return SSH_ERROR; } cert_buffer = ssh_buffer_new(); if (cert_buffer == NULL) { return SSH_ERROR; } rc = ssh_buffer_add_buffer(cert_buffer, certkey->cert); if (rc != 0) { ssh_buffer_free(cert_buffer); return SSH_ERROR; } privkey->cert = cert_buffer; privkey->cert_type = certkey->type; return SSH_OK; }
int ssh_hashbufin_add_cookie(ssh_session session, unsigned char *cookie) { int rc; session->in_hashbuf = ssh_buffer_new(); if (session->in_hashbuf == NULL) { return -1; } rc = ssh_buffer_allocate_size(session->in_hashbuf, sizeof(uint8_t) + 20 + 16); if (rc < 0) { ssh_buffer_reinit(session->in_hashbuf); return -1; } if (ssh_buffer_add_u8(session->in_hashbuf, 20) < 0) { ssh_buffer_reinit(session->in_hashbuf); return -1; } if (ssh_buffer_add_data(session->in_hashbuf,cookie, 16) < 0) { ssh_buffer_reinit(session->in_hashbuf); return -1; } return 0; }
/* * Test if the continuously growing buffer size never exceeds 2 time its * real capacity */ static void *thread_growing_buffer(void *threadid) { ssh_buffer buffer = NULL; int i; /* Unused */ (void) threadid; /* Setup */ buffer = ssh_buffer_new(); if (buffer == NULL) { pthread_exit((void *)-1); } ssh_buffer_set_secure(buffer); for (i = 0; i < BUFFER_LIMIT; ++i) { ssh_buffer_add_data(buffer,"A",1); if (buffer->used >= 128) { if (ssh_buffer_get_len(buffer) * 2 < buffer->allocated) { assert_true(ssh_buffer_get_len(buffer) * 2 >= buffer->allocated); } } } /* Teardown */ SSH_BUFFER_FREE(buffer); pthread_exit(NULL); }
/* * 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; }
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; }
int hashbufout_add_cookie(ssh_session session) { session->out_hashbuf = ssh_buffer_new(); if (session->out_hashbuf == NULL) { return -1; } if (buffer_add_u8(session->out_hashbuf, 20) < 0) { ssh_buffer_reinit(session->out_hashbuf); return -1; } if (session->server) { if (ssh_buffer_add_data(session->out_hashbuf, session->next_crypto->server_kex.cookie, 16) < 0) { ssh_buffer_reinit(session->out_hashbuf); return -1; } } else { if (ssh_buffer_add_data(session->out_hashbuf, session->next_crypto->client_kex.cookie, 16) < 0) { ssh_buffer_reinit(session->out_hashbuf); return -1; } } return 0; }
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; }
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); }
/** * @internal * * @brief Import a public key from a ssh string. * * @param[in] key_blob The key blob to import as specified in RFC 4253 section * 6.6 "Public Key Algorithms". * * @param[out] pkey A pointer where the allocated key can be stored. You * need to free the memory. * * @return SSH_OK on success, SSH_ERROR on error. * * @see ssh_key_free() */ int ssh_pki_import_pubkey_blob(const ssh_string key_blob, ssh_key *pkey) { ssh_buffer buffer; ssh_string type_s = NULL; enum ssh_keytypes_e type; int rc; if (key_blob == NULL || pkey == NULL) { return SSH_ERROR; } buffer = ssh_buffer_new(); if (buffer == NULL) { SSH_LOG(SSH_LOG_WARN, "Out of memory!"); return SSH_ERROR; } rc = ssh_buffer_add_data(buffer, ssh_string_data(key_blob), ssh_string_len(key_blob)); if (rc < 0) { SSH_LOG(SSH_LOG_WARN, "Out of memory!"); goto fail; } type_s = ssh_buffer_get_ssh_string(buffer); if (type_s == NULL) { SSH_LOG(SSH_LOG_WARN, "Out of memory!"); goto fail; } type = ssh_key_type_from_name(ssh_string_get_char(type_s)); if (type == SSH_KEYTYPE_UNKNOWN) { SSH_LOG(SSH_LOG_WARN, "Unknown key type found!"); goto fail; } ssh_string_free(type_s); if (type == SSH_KEYTYPE_RSA_CERT01 || type == SSH_KEYTYPE_DSS_CERT01) { rc = pki_import_cert_buffer(buffer, type, pkey); } else { rc = pki_import_pubkey_buffer(buffer, type, pkey); } ssh_buffer_free(buffer); return rc; fail: ssh_buffer_free(buffer); ssh_string_free(type_s); return SSH_ERROR; }
int ssh_pki_import_signature_blob(const ssh_string sig_blob, const ssh_key pubkey, ssh_signature *psig) { ssh_signature sig; enum ssh_keytypes_e type; ssh_string str; ssh_buffer buf; int rc; if (sig_blob == NULL || psig == NULL) { return SSH_ERROR; } buf = ssh_buffer_new(); if (buf == NULL) { return SSH_ERROR; } rc = ssh_buffer_add_data(buf, ssh_string_data(sig_blob), ssh_string_len(sig_blob)); if (rc < 0) { ssh_buffer_free(buf); return SSH_ERROR; } str = ssh_buffer_get_ssh_string(buf); if (str == NULL) { ssh_buffer_free(buf); return SSH_ERROR; } type = ssh_key_type_from_name(ssh_string_get_char(str)); ssh_string_free(str); str = ssh_buffer_get_ssh_string(buf); ssh_buffer_free(buf); if (str == NULL) { return SSH_ERROR; } sig = pki_signature_from_blob(pubkey, str, type); ssh_string_free(str); if (sig == NULL) { return SSH_ERROR; } *psig = sig; return SSH_OK; }
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; }
static ssh_buffer gzip_decompress(ssh_session session, ssh_buffer source, size_t maxlen) { z_stream *zin = session->current_crypto->compress_in_ctx; void *in_ptr = buffer_get_rest(source); unsigned long in_size = buffer_get_rest_len(source); unsigned char out_buf[BLOCKSIZE] = {0}; ssh_buffer dest = NULL; unsigned long len; int status; if (zin == NULL) { zin = session->current_crypto->compress_in_ctx = initdecompress(session); if (zin == NULL) { return NULL; } } dest = ssh_buffer_new(); if (dest == NULL) { return NULL; } zin->next_out = out_buf; zin->next_in = in_ptr; zin->avail_in = in_size; do { zin->avail_out = BLOCKSIZE; status = inflate(zin, Z_PARTIAL_FLUSH); if (status != Z_OK && status != Z_BUF_ERROR) { ssh_set_error(session, SSH_FATAL, "status %d inflating zlib packet", status); ssh_buffer_free(dest); return NULL; } len = BLOCKSIZE - zin->avail_out; if (buffer_add_data(dest,out_buf,len) < 0) { ssh_buffer_free(dest); return NULL; } if (buffer_get_rest_len(dest) > maxlen) { /* Size of packet exceeded, avoid a denial of service attack */ ssh_buffer_free(dest); return NULL; } zin->next_out = out_buf; } while (zin->avail_out == 0); return dest; }
ssh_string ssh_pki_do_sign_agent(ssh_session session, struct ssh_buffer_struct *buf, const ssh_key pubkey) { struct ssh_crypto_struct *crypto; ssh_string session_id; ssh_string sig_blob; ssh_buffer sig_buf; int rc; if (session->current_crypto) { crypto = session->current_crypto; } else { crypto = session->next_crypto; } /* prepend session identifier */ session_id = ssh_string_new(crypto->digest_len); if (session_id == NULL) { return NULL; } ssh_string_fill(session_id, crypto->session_id, crypto->digest_len); sig_buf = ssh_buffer_new(); if (sig_buf == NULL) { ssh_string_free(session_id); return NULL; } rc = ssh_buffer_add_ssh_string(sig_buf, session_id); if (rc < 0) { ssh_string_free(session_id); ssh_buffer_free(sig_buf); return NULL; } ssh_string_free(session_id); /* append out buffer */ if (ssh_buffer_add_buffer(sig_buf, buf) < 0) { ssh_buffer_free(sig_buf); return NULL; } /* create signature */ sig_blob = ssh_agent_sign_data(session, pubkey, sig_buf); ssh_buffer_free(sig_buf); return sig_blob; }
static void *thread_ssh_buffer_get_format_error(void *threadid) { ssh_buffer buffer = NULL; uint8_t b = 0; uint16_t w = 0; uint32_t d = 0; uint64_t q = 0; ssh_string s = NULL; char *s1 = NULL, *s2 = NULL; int rc; 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"; /* Unused */ (void) threadid; /* Setup */ buffer = ssh_buffer_new(); if (buffer == NULL) { pthread_exit((void *)-1); } ssh_buffer_set_secure(buffer); rc = ssh_buffer_add_data(buffer, verif, sizeof(verif) - 1); assert_int_equal(rc, SSH_OK); rc = ssh_buffer_unpack(buffer, "bwdqSsPb", &b, &w, &d, &q, &s, &s1, (size_t)7, &s2, &b); assert_int_equal(rc, SSH_ERROR); assert_null(s); assert_null(s1); assert_null(s2); /* Teardown */ SSH_BUFFER_FREE(buffer); pthread_exit(NULL); }
/** @internal * @brief prepends a packet with the pcap header and writes packet * on file */ int ssh_pcap_file_write_packet(ssh_pcap_file pcap, ssh_buffer packet, uint32_t original_len){ ssh_buffer header=ssh_buffer_new(); struct timeval now; int err; if(header == NULL) return SSH_ERROR; gettimeofday(&now,NULL); buffer_add_u32(header,htonl(now.tv_sec)); buffer_add_u32(header,htonl(now.tv_usec)); buffer_add_u32(header,htonl(buffer_get_rest_len(packet))); buffer_add_u32(header,htonl(original_len)); buffer_add_buffer(header,packet); err=ssh_pcap_file_write(pcap,header); ssh_buffer_free(header); return err; }
int hashbufin_add_cookie(ssh_session session, unsigned char *cookie) { session->in_hashbuf = ssh_buffer_new(); if (session->in_hashbuf == NULL) { return -1; } if (buffer_add_u8(session->in_hashbuf, 20) < 0) { ssh_buffer_reinit(session->in_hashbuf); return -1; } if (ssh_buffer_add_data(session->in_hashbuf,cookie, 16) < 0) { ssh_buffer_reinit(session->in_hashbuf); return -1; } return 0; }
/** * @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; }
ssh_string ssh_do_sign_with_agent(ssh_session session, struct ssh_buffer_struct *buf, struct ssh_public_key_struct *publickey) { struct ssh_buffer_struct *sigbuf = NULL; struct ssh_string_struct *signature = NULL; struct ssh_string_struct *session_id = NULL; struct ssh_crypto_struct *crypto = NULL; if (session->current_crypto) { crypto = session->current_crypto; } else { crypto = session->next_crypto; } /* prepend session identifier */ session_id = ssh_string_new(crypto->digest_len); if (session_id == NULL) { return NULL; } ssh_string_fill(session_id, crypto->session_id, crypto->digest_len); sigbuf = ssh_buffer_new(); if (sigbuf == NULL) { ssh_string_free(session_id); return NULL; } if (buffer_add_ssh_string(sigbuf, session_id) < 0) { ssh_buffer_free(sigbuf); ssh_string_free(session_id); return NULL; } ssh_string_free(session_id); /* append out buffer */ if (buffer_add_buffer(sigbuf, buf) < 0) { ssh_buffer_free(sigbuf); return NULL; } /* create signature */ signature = agent_sign_data(session, sigbuf, publickey); ssh_buffer_free(sigbuf); return signature; }
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; }
int sftp_reply_attr(sftp_client_message msg, sftp_attributes attr) { ssh_buffer out; out = ssh_buffer_new(); if (out == NULL) { return -1; } if (ssh_buffer_add_u32(out, msg->id) < 0 || buffer_add_attributes(out, attr) < 0 || sftp_packet_write(msg->sftp, SSH_FXP_ATTRS, out) < 0) { ssh_buffer_free(out); return -1; } ssh_buffer_free(out); return 0; }
int sftp_reply_handle(sftp_client_message msg, ssh_string handle){ ssh_buffer out; out = ssh_buffer_new(); if (out == NULL) { return -1; } if (ssh_buffer_add_u32(out, msg->id) < 0 || ssh_buffer_add_ssh_string(out, handle) < 0 || sftp_packet_write(msg->sftp, SSH_FXP_HANDLE, out) < 0) { ssh_buffer_free(out); return -1; } ssh_buffer_free(out); return 0; }
static ssh_buffer gzip_compress(ssh_session session,ssh_buffer source,int level) { z_stream *zout = session->current_crypto->compress_out_ctx; void *in_ptr = buffer_get_rest(source); unsigned long in_size = buffer_get_rest_len(source); ssh_buffer dest = NULL; unsigned char out_buf[BLOCKSIZE] = {0}; unsigned long len; int status; if(zout == NULL) { zout = session->current_crypto->compress_out_ctx = initcompress(session, level); if (zout == NULL) { return NULL; } } dest = ssh_buffer_new(); if (dest == NULL) { return NULL; } zout->next_out = out_buf; zout->next_in = in_ptr; zout->avail_in = in_size; do { zout->avail_out = BLOCKSIZE; status = deflate(zout, Z_PARTIAL_FLUSH); if (status != Z_OK) { ssh_buffer_free(dest); ssh_set_error(session, SSH_FATAL, "status %d deflating zlib packet", status); return NULL; } len = BLOCKSIZE - zout->avail_out; if (buffer_add_data(dest, out_buf, len) < 0) { ssh_buffer_free(dest); return NULL; } zout->next_out = out_buf; } while (zout->avail_out == 0); return dest; }
int sftp_reply_data(sftp_client_message msg, const void *data, int len) { ssh_buffer out; out = ssh_buffer_new(); if (out == NULL) { return -1; } if (ssh_buffer_add_u32(out, msg->id) < 0 || ssh_buffer_add_u32(out, ntohl(len)) < 0 || ssh_buffer_add_data(out, data, len) < 0 || sftp_packet_write(msg->sftp, SSH_FXP_DATA, out) < 0) { ssh_buffer_free(out); return -1; } ssh_buffer_free(out); return 0; }
static void *thread_buffer_pack_badformat(void *threadid) { ssh_buffer buffer = NULL; uint8_t b = 42; int rc; /* Unused */ (void) threadid; /* Setup */ buffer = ssh_buffer_new(); if (buffer == NULL) { pthread_exit((void *)-1); } ssh_buffer_set_secure(buffer); /* first with missing format */ rc = ssh_buffer_pack(buffer, "b", b, b); assert_int_equal(rc, SSH_ERROR); ssh_buffer_reinit(buffer); /* with additional format */ rc = ssh_buffer_pack(buffer, "bb", b); /* check that we detect the missing parameter */ assert_int_equal(rc, SSH_ERROR); /* unpack with missing format */ ssh_buffer_reinit(buffer); rc = ssh_buffer_pack(buffer, "bb", 42, 43); assert_int_equal(rc, SSH_OK); rc = ssh_buffer_unpack(buffer, "b", &b, &b); assert_int_equal(rc, SSH_ERROR); /* not doing the test with additional format as * it could crash the process */ /* Teardown */ SSH_BUFFER_FREE(buffer); pthread_exit(NULL); }