static int tls_socket_write(rad_listen_t *listener, REQUEST *request) { uint8_t *p; ssize_t rcode; listen_socket_t *sock = listener->data; p = sock->ssn->dirty_out.data; while (p < (sock->ssn->dirty_out.data + sock->ssn->dirty_out.used)) { RDEBUG3("Writing to socket %d", request->packet->sockfd); rcode = write(request->packet->sockfd, p, (sock->ssn->dirty_out.data + sock->ssn->dirty_out.used) - p); if (rcode <= 0) { RDEBUG("Error writing to TLS socket: %s", strerror(errno)); tls_socket_close(listener); return 0; } p += rcode; } sock->ssn->dirty_out.used = 0; return 1; }
int proxy_tls_send(rad_listen_t *listener, REQUEST *request) { int rcode; listen_socket_t *sock = listener->data; /* * Normal proxying calls us with the data already * encoded. The "ping home server" code does not. So, * if there's no packet, encode it here. */ if (!request->proxy->data) { request->proxy_listener->encode(request->proxy_listener, request); } DEBUG3("Proxy is writing %u bytes to SSL", (unsigned int) request->proxy->data_len); PTHREAD_MUTEX_LOCK(&sock->mutex); while ((rcode = SSL_write(sock->ssn->ssl, request->proxy->data, request->proxy->data_len)) < 0) { int err; while ((err = ERR_get_error())) { DEBUG("proxy SSL_write says %s", ERR_error_string(err, NULL)); } PTHREAD_MUTEX_UNLOCK(&sock->mutex); tls_socket_close(listener); return 0; } PTHREAD_MUTEX_UNLOCK(&sock->mutex); return 1; }
void DemoRawSockOneshotSendMac(void) { int idx; int socket_num = 0; u8 mac_addr[8]; struct tls_socket_desc socket_desc; memset(&socket_desc, 0, sizeof(struct tls_socket_desc)); socket_desc.cs_mode = SOCKET_CS_MODE_CLIENT; socket_desc.protocol = SOCKET_PROTO_UDP; for(idx = 0; idx < 4; idx++){ socket_desc.ip_addr[idx] = 255; } socket_desc.port = 65534; socket_num = tls_socket_create(&socket_desc); //printf("\nraw sk one shot sock num=%d\n",socket_num); memset(mac_addr,0,sizeof(mac_addr)); tls_get_mac_addr(mac_addr); tls_os_time_delay(200); for(idx = 0;idx < 3;idx ++) { tls_socket_send(socket_num,mac_addr, 6); tls_os_time_delay(50); } tls_socket_close(socket_num); socket_num = 0; //printf("\none shot success!\n"); }
void close_socket_fwup_demo(void) { if(fwup_skt_num>=0) { tls_socket_close(fwup_skt_num); fwup_skt_num = -1; } }
static int tls_starttls_close (CONNECTION* conn) { int rc; rc = tls_socket_close (conn); conn->conn_read = raw_socket_read; conn->conn_write = raw_socket_write; conn->conn_close = raw_socket_close; return rc; }
/** * tls_starttls_close - Close a TLS connection - Implements Connection::conn_close() */ static int tls_starttls_close(struct Connection *conn) { int rc; rc = tls_socket_close(conn); conn->conn_read = raw_socket_read; conn->conn_write = raw_socket_write; conn->conn_close = raw_socket_close; return rc; }
static int tls_socket_open (CONNECTION* conn) { if (raw_socket_open (conn) < 0) return -1; if (tls_negotiate (conn) < 0) { tls_socket_close (conn); return -1; } return 0; }
/** * tls_socket_open - Open a TLS socket - Implements Connection::conn_open() */ static int tls_socket_open(struct Connection *conn) { if (raw_socket_open(conn) < 0) return -1; if (tls_negotiate(conn) < 0) { tls_socket_close(conn); return -1; } return 0; }
int proxy_tls_send(rad_listen_t *listener, REQUEST *request) { int rcode; listen_socket_t *sock = listener->data; VERIFY_REQUEST(request); if ((listener->status != RAD_LISTEN_STATUS_INIT) && (listener->status != RAD_LISTEN_STATUS_KNOWN)) return 0; /* * Normal proxying calls us with the data already * encoded. The "ping home server" code does not. So, * if there's no packet, encode it here. */ if (!request->proxy->data) { request->proxy_listener->encode(request->proxy_listener, request); } DEBUG3("Proxy is writing %u bytes to SSL", (unsigned int) request->proxy->data_len); PTHREAD_MUTEX_LOCK(&sock->mutex); rcode = SSL_write(sock->tls_session->ssl, request->proxy->data, request->proxy->data_len); if (rcode < 0) { int err; err = ERR_get_error(); switch (err) { case SSL_ERROR_NONE: case SSL_ERROR_WANT_READ: case SSL_ERROR_WANT_WRITE: break; /* let someone else retry */ default: DEBUG("proxy SSL_write says %s", ERR_error_string(err, NULL)); DEBUG("Closing TLS socket to home server"); tls_socket_close(listener); PTHREAD_MUTEX_UNLOCK(&sock->mutex); return 0; } } PTHREAD_MUTEX_UNLOCK(&sock->mutex); return 1; }
int proxy_tls_recv(rad_listen_t *listener) { int rcode; size_t length; listen_socket_t *sock = listener->data; char buffer[256]; RADIUS_PACKET *packet; RAD_REQUEST_FUNP fun = NULL; uint8_t *data; if (!sock->data) sock->data = rad_malloc(sock->ssn->offset); data = sock->data; DEBUG3("Proxy SSL socket has data to read"); PTHREAD_MUTEX_LOCK(&sock->mutex); redo: rcode = SSL_read(sock->ssn->ssl, data, 4); if (rcode <= 0) { int err = SSL_get_error(sock->ssn->ssl, rcode); switch (err) { case SSL_ERROR_WANT_READ: case SSL_ERROR_WANT_WRITE: rcode = 0; goto redo; case SSL_ERROR_ZERO_RETURN: /* remote end sent close_notify, send one back */ SSL_shutdown(sock->ssn->ssl); case SSL_ERROR_SYSCALL: do_close: PTHREAD_MUTEX_UNLOCK(&sock->mutex); tls_socket_close(listener); return 0; default: while ((err = ERR_get_error())) { DEBUG("proxy recv says %s", ERR_error_string(err, NULL)); } goto do_close; } } length = (data[2] << 8) | data[3]; DEBUG3("Proxy received header saying we have a packet of %u bytes", (unsigned int) length); if (length > sock->ssn->offset) { radlog(L_INFO, "Received packet will be too large! Set \"fragment_size=%u\"", (data[2] << 8) | data[3]); goto do_close; } rcode = SSL_read(sock->ssn->ssl, data + 4, length); if (rcode <= 0) { switch (SSL_get_error(sock->ssn->ssl, rcode)) { case SSL_ERROR_WANT_READ: case SSL_ERROR_WANT_WRITE: rcode = 0; break; case SSL_ERROR_ZERO_RETURN: /* remote end sent close_notify, send one back */ SSL_shutdown(sock->ssn->ssl); goto do_close; default: goto do_close; } } PTHREAD_MUTEX_UNLOCK(&sock->mutex); packet = rad_alloc(0); packet->sockfd = listener->fd; packet->src_ipaddr = sock->other_ipaddr; packet->src_port = sock->other_port; packet->dst_ipaddr = sock->my_ipaddr; packet->dst_port = sock->my_port; packet->code = data[0]; packet->id = data[1]; packet->data_len = length; packet->data = rad_malloc(packet->data_len); memcpy(packet->data, data, packet->data_len); memcpy(packet->vector, packet->data + 4, 16); /* * FIXME: Client MIB updates? */ switch(packet->code) { case PW_AUTHENTICATION_ACK: case PW_ACCESS_CHALLENGE: case PW_AUTHENTICATION_REJECT: fun = rad_authenticate; break; #ifdef WITH_ACCOUNTING case PW_ACCOUNTING_RESPONSE: fun = rad_accounting; break; #endif default: /* * FIXME: Update MIB for packet types? */ radlog(L_ERR, "Invalid packet code %d sent to a proxy port " "from home server %s port %d - ID %d : IGNORED", packet->code, ip_ntoh(&packet->src_ipaddr, buffer, sizeof(buffer)), packet->src_port, packet->id); rad_free(&packet); return 0; } if (!request_proxy_reply(packet)) { rad_free(&packet); return 0; } return 1; }
static int tls_socket_recv(rad_listen_t *listener) { int doing_init = FALSE; ssize_t rcode; RADIUS_PACKET *packet; REQUEST *request; listen_socket_t *sock = listener->data; fr_tls_status_t status; RADCLIENT *client = sock->client; if (!sock->packet) { sock->packet = rad_alloc(0); if (!sock->packet) return 0; sock->packet->sockfd = listener->fd; sock->packet->src_ipaddr = sock->other_ipaddr; sock->packet->src_port = sock->other_port; sock->packet->dst_ipaddr = sock->my_ipaddr; sock->packet->dst_port = sock->my_port; if (sock->request) sock->request->packet = sock->packet; } /* * Allocate a REQUEST for debugging. */ if (!sock->request) { sock->request = request = request_alloc(); if (!sock->request) { radlog(L_ERR, "Out of memory"); return 0; } rad_assert(request->packet == NULL); rad_assert(sock->packet != NULL); request->packet = sock->packet; request->component = "<core>"; request->component = "<tls-connect>"; /* * Not sure if we should do this on every packet... */ request->reply = rad_alloc(0); if (!request->reply) return 0; request->options = RAD_REQUEST_OPTION_DEBUG2; rad_assert(sock->ssn == NULL); sock->ssn = tls_new_session(listener->tls, sock->request, listener->tls->require_client_cert); if (!sock->ssn) { request_free(&sock->request); sock->packet = NULL; return 0; } SSL_set_ex_data(sock->ssn->ssl, FR_TLS_EX_INDEX_REQUEST, (void *)request); SSL_set_ex_data(sock->ssn->ssl, FR_TLS_EX_INDEX_CERTS, (void *)&request->packet->vps); doing_init = TRUE; } rad_assert(sock->request != NULL); rad_assert(sock->request->packet != NULL); rad_assert(sock->packet != NULL); rad_assert(sock->ssn != NULL); request = sock->request; RDEBUG3("Reading from socket %d", request->packet->sockfd); PTHREAD_MUTEX_LOCK(&sock->mutex); rcode = read(request->packet->sockfd, sock->ssn->dirty_in.data, sizeof(sock->ssn->dirty_in.data)); if ((rcode < 0) && (errno == ECONNRESET)) { do_close: PTHREAD_MUTEX_UNLOCK(&sock->mutex); tls_socket_close(listener); return 0; } if (rcode < 0) { RDEBUG("Error reading TLS socket: %s", strerror(errno)); goto do_close; } /* * Normal socket close. */ if (rcode == 0) goto do_close; sock->ssn->dirty_in.used = rcode; memset(sock->ssn->dirty_in.data + sock->ssn->dirty_in.used, 0, 16); dump_hex("READ FROM SSL", sock->ssn->dirty_in.data, sock->ssn->dirty_in.used); /* * Catch attempts to use non-SSL. */ if (doing_init && (sock->ssn->dirty_in.data[0] != handshake)) { RDEBUG("Non-TLS data sent to TLS socket: closing"); goto do_close; } /* * Skip ahead to reading application data. */ if (SSL_is_init_finished(sock->ssn->ssl)) goto app; if (!tls_handshake_recv(request, sock->ssn)) { RDEBUG("FAILED in TLS handshake receive"); goto do_close; } if (sock->ssn->dirty_out.used > 0) { tls_socket_write(listener, request); PTHREAD_MUTEX_UNLOCK(&sock->mutex); return 0; } app: /* * FIXME: Run the packet through a virtual server in * order to see if we like the certificate presented by * the client. */ status = tls_application_data(sock->ssn, request); RDEBUG("Application data status %d", status); if (status == FR_TLS_MORE_FRAGMENTS) { PTHREAD_MUTEX_UNLOCK(&sock->mutex); return 0; } if (sock->ssn->clean_out.used == 0) { PTHREAD_MUTEX_UNLOCK(&sock->mutex); return 0; } dump_hex("TUNNELED DATA", sock->ssn->clean_out.data, sock->ssn->clean_out.used); /* * If the packet is a complete RADIUS packet, return it to * the caller. Otherwise... */ if ((sock->ssn->clean_out.used < 20) || (((sock->ssn->clean_out.data[2] << 8) | sock->ssn->clean_out.data[3]) != (int) sock->ssn->clean_out.used)) { RDEBUG("Received bad packet: Length %d contents %d", sock->ssn->clean_out.used, (sock->ssn->clean_out.data[2] << 8) | sock->ssn->clean_out.data[3]); goto do_close; } packet = sock->packet; packet->data = rad_malloc(sock->ssn->clean_out.used); packet->data_len = sock->ssn->clean_out.used; sock->ssn->record_minus(&sock->ssn->clean_out, packet->data, packet->data_len); packet->vps = NULL; PTHREAD_MUTEX_UNLOCK(&sock->mutex); if (!rad_packet_ok(packet, 0)) { RDEBUG("Received bad packet: %s", fr_strerror()); tls_socket_close(listener); return 0; /* do_close unlocks the mutex */ } /* * Copied from src/lib/radius.c, rad_recv(); */ if (fr_debug_flag) { char host_ipaddr[128]; if ((packet->code > 0) && (packet->code < FR_MAX_PACKET_CODE)) { RDEBUG("tls_recv: %s packet from host %s port %d, id=%d, length=%d", fr_packet_codes[packet->code], inet_ntop(packet->src_ipaddr.af, &packet->src_ipaddr.ipaddr, host_ipaddr, sizeof(host_ipaddr)), packet->src_port, packet->id, (int) packet->data_len); } else { RDEBUG("tls_recv: Packet from host %s port %d code=%d, id=%d, length=%d", inet_ntop(packet->src_ipaddr.af, &packet->src_ipaddr.ipaddr, host_ipaddr, sizeof(host_ipaddr)), packet->src_port, packet->code, packet->id, (int) packet->data_len); } } FR_STATS_INC(auth, total_requests); return 1; }
int proxy_tls_recv(rad_listen_t *listener) { listen_socket_t *sock = listener->data; char buffer[256]; RADIUS_PACKET *packet; uint8_t *data; ssize_t data_len; if (listener->status != RAD_LISTEN_STATUS_KNOWN) return 0; DEBUG3("Proxy SSL socket has data to read"); PTHREAD_MUTEX_LOCK(&sock->mutex); data_len = proxy_tls_read(listener); PTHREAD_MUTEX_UNLOCK(&sock->mutex); if (data_len < 0) { DEBUG("Closing TLS socket to home server"); PTHREAD_MUTEX_LOCK(&sock->mutex); tls_socket_close(listener); PTHREAD_MUTEX_UNLOCK(&sock->mutex); return 0; } if (data_len == 0) return 0; /* not done yet */ data = sock->data; packet = fr_radius_alloc(sock, false); packet->sockfd = listener->fd; packet->src_ipaddr = sock->other_ipaddr; packet->src_port = sock->other_port; packet->dst_ipaddr = sock->my_ipaddr; packet->dst_port = sock->my_port; packet->code = data[0]; packet->id = data[1]; packet->data_len = data_len; packet->data = talloc_array(packet, uint8_t, packet->data_len); memcpy(packet->data, data, packet->data_len); memcpy(packet->vector, packet->data + 4, 16); /* * FIXME: Client MIB updates? */ switch (packet->code) { case PW_CODE_ACCESS_ACCEPT: case PW_CODE_ACCESS_CHALLENGE: case PW_CODE_ACCESS_REJECT: break; #ifdef WITH_ACCOUNTING case PW_CODE_ACCOUNTING_RESPONSE: break; #endif default: /* * FIXME: Update MIB for packet types? */ ERROR("Invalid packet code %d sent to a proxy port " "from home server %s port %d - ID %d : IGNORED", packet->code, fr_inet_ntoh(&packet->src_ipaddr, buffer, sizeof(buffer)), packet->src_port, packet->id); fr_radius_free(&packet); return 0; } if (!request_proxy_reply(packet)) { fr_radius_free(&packet); return 0; } return 1; }
static int tls_socket_recv(rad_listen_t *listener) { bool doing_init = false; ssize_t rcode; RADIUS_PACKET *packet; REQUEST *request; listen_socket_t *sock = listener->data; fr_tls_status_t status; RADCLIENT *client = sock->client; if (!sock->packet) { sock->packet = fr_radius_alloc(sock, false); if (!sock->packet) return 0; sock->packet->sockfd = listener->fd; sock->packet->src_ipaddr = sock->other_ipaddr; sock->packet->src_port = sock->other_port; sock->packet->dst_ipaddr = sock->my_ipaddr; sock->packet->dst_port = sock->my_port; if (sock->request) sock->request->packet = talloc_steal(sock->request, sock->packet); } /* * Allocate a REQUEST for debugging, and initialize the TLS session. */ if (!sock->request) { sock->request = request = request_alloc(sock); if (!sock->request) { ERROR("Out of memory"); return 0; } rad_assert(request->packet == NULL); rad_assert(sock->packet != NULL); request->packet = talloc_steal(request, sock->packet); request->component = "<tls-connect>"; request->reply = fr_radius_alloc(request, false); if (!request->reply) return 0; rad_assert(sock->tls_session == NULL); sock->tls_session = tls_session_init_server(sock, listener->tls, sock->request, listener->tls->require_client_cert); if (!sock->tls_session) { TALLOC_FREE(sock->request); sock->packet = NULL; return 0; } SSL_set_ex_data(sock->tls_session->ssl, FR_TLS_EX_INDEX_REQUEST, (void *)request); doing_init = true; } rad_assert(sock->request != NULL); rad_assert(sock->request->packet != NULL); rad_assert(sock->packet != NULL); rad_assert(sock->tls_session != NULL); request = sock->request; RDEBUG3("Reading from socket %d", request->packet->sockfd); PTHREAD_MUTEX_LOCK(&sock->mutex); rcode = read(request->packet->sockfd, sock->tls_session->dirty_in.data, sizeof(sock->tls_session->dirty_in.data)); if ((rcode < 0) && (errno == ECONNRESET)) { do_close: PTHREAD_MUTEX_UNLOCK(&sock->mutex); DEBUG("Closing TLS socket from client port %u", sock->other_port); tls_socket_close(listener); PTHREAD_MUTEX_UNLOCK(&sock->mutex); return 0; } if (rcode < 0) { RDEBUG("Error reading TLS socket: %s", fr_syserror(errno)); goto do_close; } /* * Normal socket close. */ if (rcode == 0) goto do_close; sock->tls_session->dirty_in.used = rcode; dump_hex("READ FROM SSL", sock->tls_session->dirty_in.data, sock->tls_session->dirty_in.used); /* * Catch attempts to use non-SSL. */ if (doing_init && (sock->tls_session->dirty_in.data[0] != handshake)) { RDEBUG("Non-TLS data sent to TLS socket: closing"); goto do_close; } /* * If we need to do more initialization, do that here. */ if (!SSL_is_init_finished(sock->tls_session->ssl)) { if (!tls_handshake_recv(request, sock->tls_session)) { RDEBUG("FAILED in TLS handshake receive"); goto do_close; } /* * More ACK data to send. Do so. */ if (sock->tls_session->dirty_out.used > 0) { tls_socket_write(listener, request); PTHREAD_MUTEX_UNLOCK(&sock->mutex); return 0; } /* * FIXME: Run the request through a virtual * server in order to see if we like the * certificate presented by the client. */ } /* * Try to get application data. */ status = tls_application_data(sock->tls_session, request); RDEBUG("Application data status %d", status); if (status == FR_TLS_RECORD_FRAGMENT_MORE) { PTHREAD_MUTEX_UNLOCK(&sock->mutex); return 0; } if (sock->tls_session->clean_out.used == 0) { PTHREAD_MUTEX_UNLOCK(&sock->mutex); return 0; } /* * We now have a bunch of application data. */ dump_hex("TUNNELED DATA > ", sock->tls_session->clean_out.data, sock->tls_session->clean_out.used); /* * If the packet is a complete RADIUS packet, return it to * the caller. Otherwise... */ if ((sock->tls_session->clean_out.used < 20) || (((sock->tls_session->clean_out.data[2] << 8) | sock->tls_session->clean_out.data[3]) != (int) sock->tls_session->clean_out.used)) { RDEBUG("Received bad packet: Length %zd contents %d", sock->tls_session->clean_out.used, (sock->tls_session->clean_out.data[2] << 8) | sock->tls_session->clean_out.data[3]); goto do_close; } packet = sock->packet; packet->data = talloc_array(packet, uint8_t, sock->tls_session->clean_out.used); packet->data_len = sock->tls_session->clean_out.used; sock->tls_session->record_to_buff(&sock->tls_session->clean_out, packet->data, packet->data_len); packet->vps = NULL; PTHREAD_MUTEX_UNLOCK(&sock->mutex); if (!fr_radius_ok(packet, 0, NULL)) { if (DEBUG_ENABLED) ERROR("Receive - %s", fr_strerror()); DEBUG("Closing TLS socket from client"); PTHREAD_MUTEX_LOCK(&sock->mutex); tls_socket_close(listener); PTHREAD_MUTEX_UNLOCK(&sock->mutex); return 0; /* do_close unlocks the mutex */ } /* * Copied from src/lib/radius.c, fr_radius_recv(); */ if (fr_debug_lvl) { char host_ipaddr[INET6_ADDRSTRLEN]; if (is_radius_code(packet->code)) { RDEBUG("tls_recv: %s packet from host %s port %d, id=%d, length=%d", fr_packet_codes[packet->code], inet_ntop(packet->src_ipaddr.af, &packet->src_ipaddr.ipaddr, host_ipaddr, sizeof(host_ipaddr)), packet->src_port, packet->id, (int) packet->data_len); } else { RDEBUG("tls_recv: Packet from host %s port %d code=%d, id=%d, length=%d", inet_ntop(packet->src_ipaddr.af, &packet->src_ipaddr.ipaddr, host_ipaddr, sizeof(host_ipaddr)), packet->src_port, packet->code, packet->id, (int) packet->data_len); } } FR_STATS_INC(auth, total_requests); return 1; }