int sftp_service_handle(struct ssh2_packet *pkt) { int res; char *service = NULL; res = read_service_req(pkt, &service); if (res < 0) { destroy_pool(pkt->pool); SFTP_DISCONNECT_CONN(SFTP_SSH2_DISCONNECT_SERVICE_NOT_AVAILABLE, NULL); } destroy_pool(pkt->pool); pkt = sftp_ssh2_packet_create(service_pool); res = write_service_accept(pkt, service); if (res < 0) { destroy_pool(pkt->pool); return -1; } res = sftp_ssh2_packet_write(sftp_conn->wfd, pkt); if (res < 0) { destroy_pool(pkt->pool); return -1; } destroy_pool(pkt->pool); return 0; }
int sftp_mac_read_data(struct ssh2_packet *pkt) { struct sftp_mac *mac; HMAC_CTX *mac_ctx; mac = &(read_macs[read_mac_idx]); mac_ctx = &(read_ctxs[read_mac_idx]); if (mac->key) { unsigned char *mac_data; char *buf, *ptr; uint32_t buflen, bufsz = (sizeof(uint32_t) * 2) + pkt->packet_len, mac_len = 0; mac_data = pcalloc(pkt->pool, EVP_MAX_MD_SIZE); buflen = bufsz; ptr = buf = sftp_msg_getbuf(pkt->pool, bufsz); sftp_msg_write_int(&buf, &buflen, pkt->seqno); sftp_msg_write_int(&buf, &buflen, pkt->packet_len); sftp_msg_write_byte(&buf, &buflen, pkt->padding_len); sftp_msg_write_data(&buf, &buflen, pkt->payload, pkt->payload_len, FALSE); sftp_msg_write_data(&buf, &buflen, pkt->padding, pkt->padding_len, FALSE); #if OPENSSL_VERSION_NUMBER > 0x000907000L # if OPENSSL_VERSION_NUMBER >= 0x10000001L if (HMAC_Init_ex(mac_ctx, NULL, 0, NULL, NULL) != 1) { pr_log_writefile(sftp_logfd, MOD_SFTP_VERSION, "error resetting HMAC context: %s", sftp_crypto_get_errors()); errno = EPERM; return -1; } # else HMAC_Init_ex(mac_ctx, NULL, 0, NULL, NULL); # endif /* OpenSSL-1.0.0 and later */ #else HMAC_Init(mac_ctx, NULL, 0, NULL); #endif /* OpenSSL-0.9.7 and later */ #if OPENSSL_VERSION_NUMBER >= 0x10000001L if (HMAC_Update(mac_ctx, (unsigned char *) ptr, (bufsz - buflen)) != 1) { pr_log_writefile(sftp_logfd, MOD_SFTP_VERSION, "error adding %lu bytes of data to HMAC context: %s", (unsigned long) (bufsz - buflen), sftp_crypto_get_errors()); errno = EPERM; return -1; } if (HMAC_Final(mac_ctx, mac_data, &mac_len) != 1) { pr_log_writefile(sftp_logfd, MOD_SFTP_VERSION, "error finalizing HMAC context: %s", sftp_crypto_get_errors()); errno = EPERM; return -1; } #else HMAC_Update(mac_ctx, (unsigned char *) ptr, (bufsz - buflen)); HMAC_Final(mac_ctx, mac_data, &mac_len); #endif /* OpenSSL-1.0.0 and later */ if (mac_len == 0) { (void) pr_log_writefile(sftp_logfd, MOD_SFTP_VERSION, "error computing MAC using %s: %s", mac->algo, sftp_crypto_get_errors()); SFTP_DISCONNECT_CONN(SFTP_SSH2_DISCONNECT_MAC_ERROR, NULL); } if (mac->mac_len != 0) { mac_len = mac->mac_len; } if (mac_len != pkt->mac_len) { (void) pr_log_writefile(sftp_logfd, MOD_SFTP_VERSION, "expected %u MAC len from client, got %lu", mac_len, (unsigned long) pkt->mac_len); SFTP_DISCONNECT_CONN(SFTP_SSH2_DISCONNECT_MAC_ERROR, NULL); } if (memcmp(mac_data, pkt->mac, mac_len) != 0) { (void) pr_log_writefile(sftp_logfd, MOD_SFTP_VERSION, "MAC from client differs from expected MAC using %s", mac->algo); #ifdef SFTP_DEBUG_PACKET { unsigned int i; (void) pr_log_writefile(sftp_logfd, MOD_SFTP_VERSION, "client MAC (len %lu):", (unsigned long) pkt->mac_len); for (i = 0; i < mac_len;) { (void) pr_log_writefile(sftp_logfd, MOD_SFTP_VERSION, " %02x%02x %02x%02x %02x%02x %02x%02x", ((unsigned char *) pkt->mac)[i], ((unsigned char *) pkt->mac)[i+1], ((unsigned char *) pkt->mac)[i+2], ((unsigned char *) pkt->mac)[i+3], ((unsigned char *) pkt->mac)[i+4], ((unsigned char *) pkt->mac)[i+5], ((unsigned char *) pkt->mac)[i+6], ((unsigned char *) pkt->mac)[i+7]); i += 8; } (void) pr_log_writefile(sftp_logfd, MOD_SFTP_VERSION, "server MAC (len %lu):", (unsigned long) mac_len); for (i = 0; i < mac_len;) { (void) pr_log_writefile(sftp_logfd, MOD_SFTP_VERSION, " %02x%02x %02x%02x %02x%02x %02x%02x", ((unsigned char *) mac)[i], ((unsigned char *) mac)[i+1], ((unsigned char *) mac)[i+2], ((unsigned char *) mac)[i+3], ((unsigned char *) mac)[i+4], ((unsigned char *) mac)[i+5], ((unsigned char *) mac)[i+6], ((unsigned char *) mac)[i+7]); i += 8; } } #endif SFTP_DISCONNECT_CONN(SFTP_SSH2_DISCONNECT_MAC_ERROR, NULL); } return 0; } return 0; }