/* Transmit a literal and/or match token. * * This delightfully-named function is called either when we find a * match and need to transmit all the unmatched data leading up to it, * or when we get bored of accumulating literal data and just need to * transmit it. As a result of this second case, it is called even if * we have not matched at all! * * If i >= 0, the number of a matched token. If < 0, indicates we have * only literal data. A -1 will send a 0-token-int too, and a -2 sends * only literal data, w/o any token-int. */ static void matched(int f, struct sum_struct *s, struct map_struct *buf, OFF_T offset, int32 i) { int32 n = (int32)(offset - last_match); /* max value: block_size (int32) */ int32 j; if (DEBUG_GTE(DELTASUM, 2) && i >= 0) { rprintf(FINFO, "match at %s last_match=%s j=%d len=%ld n=%ld\n", big_num(offset), big_num(last_match), i, (long)s->sums[i].len, (long)n); } send_token(f, i, buf, last_match, n, i < 0 ? 0 : s->sums[i].len); data_transfer += n; if (i >= 0) { stats.matched_data += s->sums[i].len; n += s->sums[i].len; } for (j = 0; j < n; j += CHUNK_SIZE) { int32 n1 = MIN(CHUNK_SIZE, n - j); sum_update(map_ptr(buf, last_match + j, n1), n1); } if (i >= 0) last_match = offset + s->sums[i].len; else last_match = offset; if (buf && INFO_GTE(PROGRESS, 1)) show_progress(last_match, buf->file_size); }
/** * Transmit a literal and/or match token. * * This delightfully-named function is called either when we find a * match and need to transmit all the unmatched data leading up to it, * or when we get bored of accumulating literal data and just need to * transmit it. As a result of this second case, it is called even if * we have not matched at all! * * @param i If >0, the number of a matched token. If 0, indicates we * have only literal data. **/ static void matched(int f, struct sum_struct *s, struct map_struct *buf, OFF_T offset, int32 i) { int32 n = (int32)(offset - last_match); /* max value: block_size (int32) */ int32 j; if (verbose > 2 && i >= 0) { rprintf(FINFO, "match at %.0f last_match=%.0f j=%d len=%ld n=%ld\n", (double)offset, (double)last_match, i, (long)s->sums[i].len, (long)n); } send_token(f, i, buf, last_match, n, i < 0 ? 0 : s->sums[i].len); data_transfer += n; if (i >= 0) { stats.matched_data += s->sums[i].len; n += s->sums[i].len; } for (j = 0; j < n; j += CHUNK_SIZE) { int32 n1 = MIN(CHUNK_SIZE, n - j); sum_update(map_ptr(buf, last_match + j, n1), n1); } if (i >= 0) last_match = offset + s->sums[i].len; else last_match = offset; if (buf && do_progress) show_progress(last_match, buf->file_size); }
int send_proxy(const char *s, gss_ctx_id_t gss_context, int sck) { int return_status = BPR_SEND_PROXY_ERROR; gss_buffer_desc input_token; gss_buffer_desc output_token; OM_uint32 maj_stat, min_stat; int conf_req_flag = 1; /* Non zero value to request confidentiality */ if (gss_context != GSS_C_NO_CONTEXT) { input_token.value = (void*)s; input_token.length = strlen(s) + 1; maj_stat = gss_wrap( &min_stat, gss_context, conf_req_flag, GSS_C_QOP_DEFAULT, &input_token, NULL, &output_token); if (!GSS_ERROR(maj_stat)) { if (send_token((void*)&sck, output_token.value, output_token.length) >= 0) return_status = BPR_SEND_PROXY_OK; } gss_release_buffer(&min_stat, &output_token); } return return_status; }
int uac_token_exchange(const sip_entity* to,const TokenType toketype_) { eXosip_event_t *event; if(send_token(to,toketype_)<1) { printf("send_token error\n"); return 0; } if(uac_waitfor(NULL,EXOSIP_MESSAGE_NEW,&event)<1) { printf("uac_waitfor error event->type:%d\n",event->type); return 0; } if(handle_token(event->request,toketype_)<1) { printf("handle_token error\n"); return 0; } osip_message_t *g_answer = NULL;/*请求的确认型应答*/ eXosip_lock(); eXosip_message_build_answer(event->tid, 200, &g_answer);/*Build default Answer for request*/ eXosip_message_send_answer(event->tid, 200, g_answer);/*按照规则回复200OK*/ eXosip_unlock(); eXosip_event_free (event); printf("uac_token_exchange-----finished\n"); return 1; }
int main() { initialize_buffers(); printf("\n\nHej from " ALT_CPU_NAME "!\n"); //declare communication variables here // three dct and huffman_encode steps here smaller_block dct_y01_input; smaller_block dct_y10_input; smaller_block dct_y11_input; smaller_block dct_y01_output; smaller_block dct_y10_output; smaller_block dct_y11_output; huffman_encoding_output huffman_y01_output; huffman_encoding_output huffman_y10_output; huffman_encoding_output huffman_y11_output; while (1) { receive_token(2, 9, &dct_y01_input); dct_func(&dct_y01_output, &dct_y01_input); receive_token(2, 11, &dct_y10_input); dct_func(&dct_y10_output, &dct_y10_input); receive_token(2, 13, &dct_y11_input); dct_func(&dct_y11_output, &dct_y11_input); huffman_encode_func(&huffman_y01_output, &dct_y01_output); send_token(10, 15, &huffman_y01_output); huffman_encode_func(&huffman_y10_output, &dct_y10_output); send_token(12, 15, &huffman_y10_output); huffman_encode_func(&huffman_y11_output, &dct_y11_output); send_token(14, 15, &huffman_y11_output); //receive_token(sender, receiver, pointer_to_data); //call process functions here //send_token(sender, receiver, pointer_to_data); } }
void ClientHandler::loop_memoria() { bool tengo_el_token = false; do { try { tengo_el_token = false; grupo->lock_token(); tengo_el_token = true; } catch (InterruptedSyscall & interruption) { Log::alert(interruption.what()); tengo_el_token = false; leave = true; } try { send_token(); if (recv_token() == 0) { leave = true; } } catch (OSError & error) { #if DEBUG_CLIENT_HANDLER==1 std::cout << nombre_cliente << "(" << nombre_grupo << ") Saliendo" << std::endl; #endif Log::alert(error.what()); leave = true; } try { if (leave) { leave_group(); } if (tengo_el_token) { grupo->release_token(&cola_token_manager); } tengo_el_token = false; } catch (OSError & error) { } } while (!leave); try { mensaje.respuesta = mensajes::LEAVE_OK; socket.sendsome(&mensaje, sizeof(mensajes::mensajes_local_broker_token_t)); } catch (OSError & error) { } }
static void xact_out(usb_addr_t addr, usb_endp_t endpoint, uint8_t *data, uint16_t len) { send_token(PID_OUT, addr, endpoint); send_data(next_data(), data, len); recv_handshake(); }
int delegate_proxy(const char *proxy_file, gss_cred_id_t cred_handle, gss_ctx_id_t gss_context, int sck) { int return_status = BPR_DELEGATE_PROXY_ERROR; int send_status; gss_buffer_desc input_token, output_token; gss_buffer_desc rcv_token, snd_token; OM_uint32 del_maj_stat, maj_stat, min_stat; int conf_req_flag = 1; /* Non zero value to request confidentiality */ if (gss_context != GSS_C_NO_CONTEXT) { /* Bootstrap call */ del_maj_stat = gss_init_delegation(&min_stat, gss_context, cred_handle, GSS_C_NO_OID, GSS_C_NO_OID_SET, GSS_C_NO_BUFFER_SET, GSS_C_NO_BUFFER, GSS_C_GLOBUS_SSL_COMPATIBLE, 0, &snd_token); while (1) /* Will break after the last token has been sent */ { maj_stat = gss_wrap( &min_stat, gss_context, conf_req_flag, GSS_C_QOP_DEFAULT, &snd_token, NULL, &output_token); gss_release_buffer(&min_stat, &snd_token); if (!GSS_ERROR(maj_stat)) { send_status = send_token((void*)&sck, output_token.value, output_token.length); gss_release_buffer(&min_stat, &output_token); if (send_status < 0) { break; } } else { break; } if (del_maj_stat != GSS_S_CONTINUE_NEEDED) break; if (get_token(&sck, &input_token.value, &input_token.length) < 0) break; maj_stat = gss_unwrap( &min_stat, gss_context, &input_token, &rcv_token, NULL, NULL); gss_release_buffer(&min_stat, &input_token); del_maj_stat = gss_init_delegation(&min_stat, gss_context, cred_handle, GSS_C_NO_OID, GSS_C_NO_OID_SET, GSS_C_NO_BUFFER_SET, &rcv_token, GSS_C_GLOBUS_SSL_COMPATIBLE, 0, &snd_token); gss_release_buffer(&min_stat, &rcv_token); } } if (del_maj_stat == GSS_S_COMPLETE) return_status = BPR_DELEGATE_PROXY_OK; return return_status; }
int receive_delegated_proxy(char **s, gss_ctx_id_t gss_context, int sck) { char *buf; int return_status = BPR_RECEIVE_DELEGATED_PROXY_ERROR; int send_status; gss_buffer_desc input_token,output_token; gss_buffer_desc snd_token, rcv_token; gss_buffer_desc cred_token; gss_cred_id_t delegated_cred = GSS_C_NO_CREDENTIAL; OM_uint32 del_maj_stat, maj_stat, min_stat, time_rec; int conf_req_flag = 1; /* Non zero value to request confidentiality */ del_maj_stat = GSS_S_CONTINUE_NEEDED; if (gss_context != GSS_C_NO_CONTEXT) { while (del_maj_stat == GSS_S_CONTINUE_NEEDED) { /* get_token can return -1 on error or GLOBUS_GSS_ASSIST_TOKEN_EOF==3 */ if (get_token(&sck, &input_token.value, &input_token.length) != 0) break; maj_stat = gss_unwrap( &min_stat, gss_context, &input_token, &rcv_token, NULL, NULL); gss_release_buffer(&min_stat, &input_token); if (!GSS_ERROR(maj_stat)) { del_maj_stat=gss_accept_delegation(&min_stat, gss_context, GSS_C_NO_OID_SET, GSS_C_NO_BUFFER_SET, &rcv_token, GSS_C_GLOBUS_SSL_COMPATIBLE, 0, &time_rec, &delegated_cred, NULL, &snd_token); } else break; gss_release_buffer(&min_stat, &rcv_token); if (del_maj_stat != GSS_S_CONTINUE_NEEDED) break; maj_stat = gss_wrap( &min_stat, gss_context, conf_req_flag, GSS_C_QOP_DEFAULT, &snd_token, NULL, &output_token); gss_release_buffer(&min_stat, &snd_token); if (!GSS_ERROR(maj_stat)) { send_status = send_token((void*)&sck, output_token.value, output_token.length); gss_release_buffer(&min_stat, &output_token); if (send_status < 0) { break; } } else { break; } } } if (del_maj_stat == GSS_S_COMPLETE) { /* Export credential to a string */ maj_stat = gss_export_cred(&min_stat, delegated_cred, GSS_C_NO_OID, 0, &cred_token); if (maj_stat == GSS_S_COMPLETE) { if (s != NULL) { *s = (char *)malloc(cred_token.length + 1); if (*s != NULL) { memcpy(*s, cred_token.value, cred_token.length); (*s)[cred_token.length]='\000'; return_status = BPR_RECEIVE_DELEGATED_PROXY_OK; } } } gss_release_buffer(&min_stat, &cred_token); } return return_status; }
/* * Function: client_establish_context * * Purpose: establishes a GSS-API context with a specified service and * returns the context handle * * Arguments: * * s (r) an established TCP connection to the service * service_name(r) the ASCII service name of the service * gss_flags (r) GSS-API delegation flag (if any) * auth_flag (r) whether to actually do authentication * v1_format (r) whether the v1 sample protocol should be used * oid (r) OID of the mechanism to use * context (w) the established GSS-API context * ret_flags (w) the returned flags from init_sec_context * * Returns: 0 on success, -1 on failure * * Effects: * * service_name is imported as a GSS-API name and a GSS-API context is * established with the corresponding service; the service should be * listening on the TCP connection s. The default GSS-API mechanism * is used, and mutual authentication and replay detection are * requested. * * If successful, the context handle is returned in context. If * unsuccessful, the GSS-API error messages are displayed on stderr * and -1 is returned. */ static int client_establish_context(int s, char *service_name, OM_uint32 gss_flags, int auth_flag, int v1_format, gss_OID oid, char *username, char *password, gss_ctx_id_t *gss_context, OM_uint32 *ret_flags) { if (auth_flag) { gss_buffer_desc send_tok, recv_tok, *token_ptr; gss_name_t target_name; OM_uint32 maj_stat, min_stat, init_sec_min_stat; int token_flags; gss_cred_id_t cred = GSS_C_NO_CREDENTIAL; gss_name_t gss_username = GSS_C_NO_NAME; gss_OID_set_desc mechs, *mechsp = GSS_C_NO_OID_SET; #ifndef MECH_EAP struct gss_channel_bindings_struct cb = {GSS_C_AF_NULLADDR, {0, NULL}, GSS_C_AF_NULLADDR, {0, NULL}, {strlen("HLJHLJHLJHLJHJKLHLJHLJH"), "HLJHLJHLJHLJHJKLHLJHLJH"}}; #endif if (spnego) { mechs.elements = &gss_spnego_mechanism_oid_desc; mechs.count = 1; mechsp = &mechs; } else if (oid != GSS_C_NO_OID) { mechs.elements = oid; mechs.count = 1; mechsp = &mechs; } else { mechs.elements = NULL; mechs.count = 0; } if (username != NULL) { send_tok.value = username; send_tok.length = strlen(username); maj_stat = gss_import_name(&min_stat, &send_tok, (gss_OID) gss_nt_user_name, &gss_username); if (maj_stat != GSS_S_COMPLETE) { display_status("parsing client name", maj_stat, min_stat); return -1; } } if (password != NULL) { gss_buffer_desc pwbuf; pwbuf.value = password; pwbuf.length = strlen(password); maj_stat = gss_acquire_cred_with_password(&min_stat, gss_username, &pwbuf, 0, mechsp, GSS_C_INITIATE, &cred, NULL, NULL); } else if (gss_username != GSS_C_NO_NAME) { maj_stat = gss_acquire_cred(&min_stat, gss_username, 0, mechsp, GSS_C_INITIATE, &cred, NULL, NULL); } else maj_stat = GSS_S_COMPLETE; if (maj_stat != GSS_S_COMPLETE) { display_status("acquiring creds", maj_stat, min_stat); gss_release_name(&min_stat, &gss_username); return -1; } if (spnego && oid != GSS_C_NO_OID) { gss_OID_set_desc neg_mechs; neg_mechs.elements = oid; neg_mechs.count = 1; maj_stat = gss_set_neg_mechs(&min_stat, cred, &neg_mechs); if (maj_stat != GSS_S_COMPLETE) { display_status("setting neg mechs", maj_stat, min_stat); gss_release_name(&min_stat, &gss_username); gss_release_cred(&min_stat, &cred); return -1; } } gss_release_name(&min_stat, &gss_username); /* * Import the name into target_name. Use send_tok to save * local variable space. */ send_tok.value = service_name; send_tok.length = strlen(service_name); maj_stat = gss_import_name(&min_stat, &send_tok, (gss_OID) gss_nt_service_name, &target_name); if (maj_stat != GSS_S_COMPLETE) { display_status("parsing name", maj_stat, min_stat); return -1; } if (!v1_format) { if (send_token(s, TOKEN_NOOP | TOKEN_CONTEXT_NEXT, empty_token) < 0) { (void) gss_release_name(&min_stat, &target_name); return -1; } } /* * Perform the context-establishement loop. * * On each pass through the loop, token_ptr points to the token * to send to the server (or GSS_C_NO_BUFFER on the first pass). * Every generated token is stored in send_tok which is then * transmitted to the server; every received token is stored in * recv_tok, which token_ptr is then set to, to be processed by * the next call to gss_init_sec_context. * * GSS-API guarantees that send_tok's length will be non-zero * if and only if the server is expecting another token from us, * and that gss_init_sec_context returns GSS_S_CONTINUE_NEEDED if * and only if the server has another token to send us. */ token_ptr = GSS_C_NO_BUFFER; *gss_context = GSS_C_NO_CONTEXT; do { maj_stat = gss_init_sec_context(&init_sec_min_stat, cred, gss_context, target_name, mechs.elements, gss_flags, 0, #ifdef MECH_EAP NULL, /* channel bindings */ #else &cb, #endif token_ptr, NULL, /* mech type */ &send_tok, ret_flags, NULL); /* time_rec */ if (token_ptr != GSS_C_NO_BUFFER) free(recv_tok.value); if (send_tok.length != 0) { if (verbose) printf("Sending init_sec_context token (size=%d)...", (int) send_tok.length); if (send_token(s, v1_format ? 0 : TOKEN_CONTEXT, &send_tok) < 0) { (void) gss_release_buffer(&min_stat, &send_tok); (void) gss_release_name(&min_stat, &target_name); return -1; } } (void) gss_release_buffer(&min_stat, &send_tok); if (maj_stat != GSS_S_COMPLETE && maj_stat != GSS_S_CONTINUE_NEEDED) { display_status("initializing context", maj_stat, init_sec_min_stat); (void) gss_release_name(&min_stat, &target_name); if (*gss_context != GSS_C_NO_CONTEXT) gss_delete_sec_context(&min_stat, gss_context, GSS_C_NO_BUFFER); return -1; } if (maj_stat == GSS_S_CONTINUE_NEEDED) { if (verbose) printf("continue needed..."); if (recv_token(s, &token_flags, &recv_tok) < 0) { (void) gss_release_name(&min_stat, &target_name); return -1; } token_ptr = &recv_tok; } if (verbose) printf("\n"); } while (maj_stat == GSS_S_CONTINUE_NEEDED); (void) gss_release_cred(&min_stat, &cred); (void) gss_release_name(&min_stat, &target_name); } else { if (send_token(s, TOKEN_NOOP, empty_token) < 0) return -1; } return 0; }
/* * Function: server_establish_context * * Purpose: establishses a GSS-API context as a specified service with * an incoming client, and returns the context handle and associated * client name * * Arguments: * * s (r) an established TCP connection to the client * service_creds (r) server credentials, from gss_acquire_cred * context (w) the established GSS-API context * client_name (w) the client's ASCII name * * Returns: 0 on success, -1 on failure * * Effects: * * Any valid client request is accepted. If a context is established, * its handle is returned in context and the client name is returned * in client_name and 0 is returned. If unsuccessful, an error * message is displayed and -1 is returned. */ static int server_establish_context(int s, gss_cred_id_t server_creds, gss_ctx_id_t *context, gss_buffer_t client_name, OM_uint32 *ret_flags) { gss_buffer_desc send_tok, recv_tok; gss_name_t client; gss_OID doid; OM_uint32 maj_stat, min_stat, acc_sec_min_stat; gss_buffer_desc oid_name; int token_flags; if (recv_token(s, &token_flags, &recv_tok) < 0) return -1; if (recv_tok.value) { free(recv_tok.value); recv_tok.value = NULL; } if (!(token_flags & TOKEN_NOOP)) { if (logfile) fprintf(logfile, "Expected NOOP token, got %d token instead\n", token_flags); return -1; } *context = GSS_C_NO_CONTEXT; if (token_flags & TOKEN_CONTEXT_NEXT) { do { if (recv_token(s, &token_flags, &recv_tok) < 0) return -1; if (verbose && logfile) { fprintf(logfile, "Received token (size=%d): \n", (int) recv_tok.length); print_token(&recv_tok); } maj_stat = gss_accept_sec_context(&acc_sec_min_stat, context, server_creds, &recv_tok, GSS_C_NO_CHANNEL_BINDINGS, &client, &doid, &send_tok, ret_flags, NULL, /* time_rec */ NULL); /* del_cred_handle */ if (recv_tok.value) { free(recv_tok.value); recv_tok.value = NULL; } if (send_tok.length != 0) { if (verbose && logfile) { fprintf(logfile, "Sending accept_sec_context token (size=%d):\n", (int) send_tok.length); print_token(&send_tok); } if (send_token(s, TOKEN_CONTEXT, &send_tok) < 0) { if (logfile) fprintf(logfile, "failure sending token\n"); return -1; } (void) gss_release_buffer(&min_stat, &send_tok); } if (maj_stat != GSS_S_COMPLETE && maj_stat != GSS_S_CONTINUE_NEEDED) { display_status("accepting context", maj_stat, acc_sec_min_stat); if (*context != GSS_C_NO_CONTEXT) gss_delete_sec_context(&min_stat, context, GSS_C_NO_BUFFER); return -1; } if (verbose && logfile) { if (maj_stat == GSS_S_CONTINUE_NEEDED) fprintf(logfile, "continue needed...\n"); else fprintf(logfile, "\n"); fflush(logfile); } } while (maj_stat == GSS_S_CONTINUE_NEEDED); /* display the flags */ display_ctx_flags(*ret_flags); if (verbose && logfile) { maj_stat = gss_oid_to_str(&min_stat, doid, &oid_name); if (maj_stat != GSS_S_COMPLETE) { display_status("converting oid->string", maj_stat, min_stat); return -1; } fprintf(logfile, "Accepted connection using mechanism OID %.*s.\n", (int) oid_name.length, (char *) oid_name.value); (void) gss_release_buffer(&min_stat, &oid_name); } maj_stat = gss_display_name(&min_stat, client, client_name, &doid); if (maj_stat != GSS_S_COMPLETE) { display_status("displaying name", maj_stat, min_stat); return -1; } enumerateAttributes(&min_stat, client, TRUE); showLocalIdentity(&min_stat, client); maj_stat = gss_release_name(&min_stat, &client); if (maj_stat != GSS_S_COMPLETE) { display_status("releasing name", maj_stat, min_stat); return -1; } } else { client_name->length = *ret_flags = 0; if (logfile) fprintf(logfile, "Accepted unauthenticated connection.\n"); } return 0; }
void send_inplace_data(int f_out,struct map_struct * buf, struct copy_graph_node *copy_graph_head, struct add_list * add_list) { while(copy_graph_head!= NULL) { struct copy_graph_node * temp_copy_node; //rprintf(FINFO,"Pulling off of topo list: %08x\n",copy_graph_head->u.copy); if(copy_graph_head->visited ==DELETED) { buffer_add(add_list,copy_graph_head->u.copy->block * BLOCK_SIZE, copy_graph_head->u.copy->length); extra_bytes += copy_graph_head->u.copy->length; stats.total_extra_written += copy_graph_head->u.copy->length; continue; } send_token(f_out,copy_graph_head->u.copy->block,buf, copy_graph_head->u.copy->target,0,copy_graph_head->u.copy->length); extra_bytes += sizeof(long int); if(inplace == 2) { OFF_T start = copy_graph_head->u.copy_trim->target; if(copy_graph_head->u.copy_trim->b_offset > 0) { if(verbose>4) { rprintf(FINFO,"sending: start=%.0f " "end=%.0f\n", (double)copy_graph_head->u.copy_trim->target, (double)(copy_graph_head->u.copy_trim->target +copy_graph_head->u.copy_trim->b_offset)); } //send_token(f_out,-2,buf,start, // copy_graph_head->u.copy_trim->b_offset,0); buffer_add(add_list,start,copy_graph_head->u.copy_trim->b_offset); extra_bytes += sizeof(long int); extra_bytes += copy_graph_head->u.copy_trim->b_offset; stats.total_extra_written += sizeof(long int)+ copy_graph_head->u.copy_trim->b_offset; } if(copy_graph_head->u.copy_trim->e_offset < copy_graph_head->u.copy_trim->length) { if(verbose>4) { rprintf(FINFO,"sending: start=%.0f " "end=%.0f\n", (double)(start+copy_graph_head->u.copy_trim->e_offset), (double)(copy_graph_head->u.copy_trim->length -copy_graph_head->u.copy_trim->e_offset)); } /*send_token(f_out,-2,buf,start +copy_graph_head->u.copy_trim->e_offset, copy_graph_head->u.copy_trim->length -copy_graph_head->u.copy_trim->e_offset,0);*/ buffer_add(add_list,start +copy_graph_head->u.copy_trim->e_offset, copy_graph_head->u.copy_trim->length -copy_graph_head->u.copy_trim->e_offset); extra_bytes += sizeof(long int); extra_bytes += copy_graph_head->u.copy_trim->length - copy_graph_head->u.copy_trim->e_offset; stats.total_extra_written +=sizeof(long int) + copy_graph_head->u.copy_trim->length - copy_graph_head->u.copy_trim->e_offset; } } temp_copy_node = copy_graph_head; copy_graph_head = copy_graph_head->next; update_extra_memory(-((inplace==1)?sizeof(struct copy):sizeof(struct copy_trim))); free(temp_copy_node->u.copy); update_extra_memory(-sizeof(struct copy_graph_node)); free(temp_copy_node); } while(add_list->head != NULL) { send_token(f_out,-2,buf, add_list->head->add.offset,add_list->head->add.length,0); extra_bytes += sizeof(long int); stats.total_extra_written += sizeof(long int); add_list->tail = add_list->head; add_list->head = add_list->head->next; update_extra_memory(-sizeof(struct add_list_node)); free(add_list->tail); } /* send done */ send_token(f_out,-1,buf,0,0,0); if(do_stats) { rprintf(FINFO, "Extra bytes sent: %d\n", extra_bytes); } }
/* * Establish a secure context using the GSS-API. A handshake is attempted in * order to detect a non-authenticating server. The server IP address is obtained * from the socket and is used to perform an fqdn lookup in case a DNS alias is * used as a host spec, this ensures we authenticate against the correct server. * We attempt to extract the server principal name, a service, from the * environment, if it is not specified we use "host/" as a default. * * @pram to_net_sd. Socket to write to. * * @pram from_net_sd. Socket to read from. * * @param req_flags. A representation of the security services to * be requested. * * @param ret_flags. A representation of the security services * provided/supported by the underlying mechanism * to be returned to the invoking function. * * Returns 0 on success, otherwise error. */ static int dcc_gssapi_establish_secure_context(int to_net_sd, int from_net_sd, OM_uint32 req_flags, OM_uint32 *ret_flags) { char *ext_princ_name = NULL; char *full_name = NULL; char *princ_env_val = NULL; gss_buffer_desc input_tok = GSS_C_EMPTY_BUFFER; gss_buffer_desc name_buffer = GSS_C_EMPTY_BUFFER; gss_buffer_desc output_tok = GSS_C_EMPTY_BUFFER; gss_name_t int_serv_name; gss_OID name_type; int ret; OM_uint32 major_status, minor_status, return_status; socklen_t addr_len; struct hostent *hp; struct sockaddr_in addr; addr_len = sizeof(addr); if ((ret = getpeername(to_net_sd, &addr, &addr_len)) != 0) { rs_log_error("Failed to look up peer address using socket \"%d\": %s.", to_net_sd, hstrerror(h_errno)); return EXIT_CONNECT_FAILED; } rs_log_info("Successfully looked up IP address %s using socket %d.", inet_ntoa(addr.sin_addr), to_net_sd); if ((hp = gethostbyaddr((char *) &addr.sin_addr, sizeof(addr.sin_addr), AF_INET)) == NULL) { rs_log_error("Failed to look up host by address \"%s\": %s.", inet_ntoa(addr.sin_addr), hstrerror(h_errno)); return EXIT_CONNECT_FAILED; } rs_log_info("Successfully looked up host %s using IP address %s.", hp->h_name, inet_ntoa(addr.sin_addr)); if ((full_name = malloc(strlen(hp->h_name) + 1)) == NULL) { rs_log_error("malloc failed : %ld bytes: out of memory.", (long) (strlen(hp->h_name) + 1)); return EXIT_OUT_OF_MEMORY; } strcpy(full_name, hp->h_name); if ((princ_env_val = getenv("DISTCC_PRINCIPAL"))) { if (asprintf(&ext_princ_name, "%s@%s", princ_env_val, full_name) < 0) { rs_log_error("Failed to allocate memory for asprintf."); return EXIT_OUT_OF_MEMORY; } name_type = GSS_C_NT_HOSTBASED_SERVICE; } else { if (asprintf(&ext_princ_name, "host/%s", full_name) < 0) { rs_log_error("Failed to allocate memory for asprintf."); return EXIT_OUT_OF_MEMORY; } name_type = GSS_C_NT_USER_NAME; } free(full_name); name_buffer.value = ext_princ_name; name_buffer.length = strlen(ext_princ_name); if ((major_status = gss_import_name(&minor_status, &name_buffer, name_type, &int_serv_name)) != GSS_S_COMPLETE) { rs_log_error("Failed to import service name to internal GSS-API format."); return EXIT_GSSAPI_FAILED; } input_tok.value = NULL; input_tok.length = 0; output_tok.value = NULL; output_tok.length = 0; if ((ret = dcc_gssapi_send_handshake(to_net_sd, from_net_sd)) != 0) { return ret; } do { major_status = gss_init_sec_context(&minor_status, GSS_C_NO_CREDENTIAL, &distcc_ctx_handle, int_serv_name, GSS_C_NO_OID, req_flags, 0, GSS_C_NO_CHANNEL_BINDINGS, &input_tok, NULL, &output_tok, ret_flags, NULL); if (GSS_ERROR(major_status)) { rs_log_crit("Failed to initiate a secure context."); dcc_gssapi_status_to_log(major_status, GSS_C_GSS_CODE); dcc_gssapi_status_to_log(minor_status, GSS_C_MECH_CODE); return EXIT_GSSAPI_FAILED; } if (output_tok.length > 0) { if ((ret = send_token(to_net_sd, &output_tok)) != 0) { dcc_gssapi_cleanup(&input_tok, &output_tok, &int_serv_name); return ret; } else { if ((return_status = gss_release_buffer(&minor_status, &output_tok)) != GSS_S_COMPLETE) { rs_log_error("Failed to release buffer."); } } } if (input_tok.length > 0) { if ((return_status = gss_release_buffer(&minor_status, &input_tok)) != GSS_S_COMPLETE) { rs_log_error("Failed to release buffer."); } } if (major_status == GSS_S_CONTINUE_NEEDED) { if ((ret = recv_token(from_net_sd, &input_tok)) != 0) { dcc_gssapi_cleanup(&input_tok, &output_tok, &int_serv_name); return ret; } } } while (major_status != GSS_S_COMPLETE); rs_log_info("Successfully authenticated %s.", ext_princ_name); dcc_gssapi_cleanup(&input_tok, &output_tok, &int_serv_name); if ((major_status = gss_release_buffer(&minor_status, &name_buffer)) != GSS_S_COMPLETE) { rs_log_error("Failed to release buffer."); } return 0; }