int httpd_main(int argc, char *argv[]) { char *p = NULL, *r; char *buffer; int number = 0, ret; struct netbuf *buf; send_accept(); buffer = kz_kmalloc(DEFAULT_NETBUF_SIZE); while (1) { kz_recv(MSGBOX_ID_HTTPD, NULL, (void *)&buf); switch (buf->cmd) { case TCP_CMD_ESTAB: number = buf->option.tcp.establish.number; p = buffer; break; case TCP_CMD_CLOSE: number = 0; send_accept(); break; case TCP_CMD_RECV: memcpy(p, buf->top, buf->size); p += buf->size; *p = '\0'; r = strchr(buffer, '\n'); if (r) { *r = '\0'; r++; ret = parse(number, buffer); memmove(buffer, r, p - r + 1); p -= (r - buffer); if (ret) send_close(number); } break; } kz_kmfree(buf); } return 0; }
void i2p_stream::read_line(error_code const& e, boost::shared_ptr<handler_type> h) { TORRENT_ASSERT(m_magic == 0x1337); #if defined TORRENT_ASIO_DEBUGGING complete_async("i2p_stream::read_line"); #endif if (handle_error(e, h)) return; int read_pos = m_buffer.size(); // look for \n which means end of the response if (m_buffer[read_pos - 1] != '\n') { #if defined TORRENT_ASIO_DEBUGGING add_outstanding_async("i2p_stream::read_line"); #endif // read another byte from the socket m_buffer.resize(read_pos + 1); async_read(m_sock, boost::asio::buffer(&m_buffer[read_pos], 1) , boost::bind(&i2p_stream::read_line, this, _1, h)); return; } m_buffer[read_pos - 1] = 0; if (m_command == cmd_incoming) { // this is the line containing the destination // of the incoming connection in an accept call m_dest = &m_buffer[0]; (*h)(e); std::vector<char>().swap(m_buffer); return; } error_code invalid_response(i2p_error::parse_failed , get_i2p_category()); // null-terminate the string and parse it m_buffer.push_back(0); char* ptr = &m_buffer[0]; char* next = ptr; char const* expect1 = 0; char const* expect2 = 0; switch (m_state) { case read_hello_response: expect1 = "HELLO"; expect2 = "REPLY"; break; case read_connect_response: case read_accept_response: expect1 = "STREAM"; expect2 = "STATUS"; break; case read_session_create_response: expect1 = "SESSION"; expect2 = "STATUS"; break; case read_name_lookup_response: expect1 = "NAMING"; expect2 = "REPLY"; break; } // fprintf(stderr, "<<< %s\n", &m_buffer[0]); ptr = string_tokenize(next, ' ', &next); if (ptr == 0 || expect1 == 0 || strcmp(expect1, ptr)) { handle_error(invalid_response, h); return; } ptr = string_tokenize(next, ' ', &next); if (ptr == 0 || expect2 == 0 || strcmp(expect2, ptr)) { handle_error(invalid_response, h); return; } int result = 0; // char const* message = 0; // float version = 3.0f; for(;;) { char* name = string_tokenize(next, '=', &next); if (name == 0) break; // fprintf(stderr, "name=\"%s\"\n", name); char* ptr2 = string_tokenize(next, ' ', &next); if (ptr2 == 0) { handle_error(invalid_response, h); return; } // fprintf(stderr, "value=\"%s\"\n", ptr2); if (strcmp("RESULT", name) == 0) { if (strcmp("OK", ptr2) == 0) result = i2p_error::no_error; else if (strcmp("CANT_REACH_PEER", ptr2) == 0) result = i2p_error::cant_reach_peer; else if (strcmp("I2P_ERROR", ptr2) == 0) result = i2p_error::i2p_error; else if (strcmp("INVALID_KEY", ptr2) == 0) result = i2p_error::invalid_key; else if (strcmp("INVALID_ID", ptr2) == 0) result = i2p_error::invalid_id; else if (strcmp("TIMEOUT", ptr2) == 0) result = i2p_error::timeout; else if (strcmp("KEY_NOT_FOUND", ptr2) == 0) result = i2p_error::key_not_found; else if (strcmp("DUPLICATED_ID", ptr2) == 0) result = i2p_error::duplicated_id; else result = i2p_error::num_errors; // unknown error } else if (strcmp("MESSAGE", name) == 0) { // message = ptr2; } else if (strcmp("VERSION", name) == 0) { // version = float(atof(ptr2)); } else if (strcmp("VALUE", name) == 0) { m_name_lookup = ptr2; } else if (strcmp("DESTINATION", name) == 0) { m_dest = ptr2; } } error_code ec(result, get_i2p_category()); switch (result) { case i2p_error::no_error: case i2p_error::invalid_key: break; default: { handle_error (ec, h); return; } } switch (m_state) { case read_hello_response: switch (m_command) { case cmd_create_session: send_session_create(h); break; case cmd_accept: send_accept(h); break; case cmd_connect: send_connect(h); break; default: (*h)(e); std::vector<char>().swap(m_buffer); } break; case read_connect_response: case read_session_create_response: case read_name_lookup_response: (*h)(ec); std::vector<char>().swap(m_buffer); break; case read_accept_response: // the SAM bridge is waiting for an incoming // connection. // wait for one more line containing // the destination of the remote peer m_command = cmd_incoming; m_buffer.resize(1); #if defined TORRENT_ASIO_DEBUGGING add_outstanding_async("i2p_stream::read_line"); #endif async_read(m_sock, boost::asio::buffer(m_buffer) , boost::bind(&i2p_stream::read_line, this, _1, h)); break; } return; }
OM_uint32 KRB5_LIB_FUNCTION gss_accept_sec_context_spnego (OM_uint32 * minor_status, gss_ctx_id_t * context_handle, const gss_cred_id_t acceptor_cred_handle, const gss_buffer_t input_token_buffer, const gss_channel_bindings_t input_chan_bindings, gss_name_t * src_name, gss_OID * mech_type, gss_buffer_t output_token, OM_uint32 * ret_flags, OM_uint32 * time_rec, gss_cred_id_t * delegated_cred_handle) { NegTokenInit init_token; OM_uint32 major_status; OM_uint32 minor_status2; gss_buffer_desc ibuf, obuf; gss_buffer_t ot = NULL; unsigned char *buf; size_t buf_size; size_t len, taglen, ni_len; int found = 0; int ret, i; memset(&init_token, 0, sizeof(init_token)); ret = gssapi_spnego_decapsulate(minor_status, input_token_buffer, &buf, &buf_size, GSS_SPNEGO_MECH); if (ret) return ret; ret = der_match_tag_and_length(buf, buf_size, KERB_CTXT, CONS, 0, &len, &taglen); if (ret) return ret; ret = decode_NegTokenInit(buf + taglen, len, &init_token, &ni_len); if (ret) { *minor_status = EINVAL; /* XXX */ return GSS_S_DEFECTIVE_TOKEN; } if (init_token.mechTypes == NULL) return send_reject (minor_status, output_token); for (i = 0; !found && i < init_token.mechTypes->len; ++i) { unsigned char mechbuf[17]; size_t mech_len; ret = der_put_oid (mechbuf + sizeof(mechbuf) - 1, sizeof(mechbuf), &init_token.mechTypes->val[i], &mech_len); if (ret) return GSS_S_DEFECTIVE_TOKEN; if (mech_len == GSS_KRB5_MECH->length && memcmp(GSS_KRB5_MECH->elements, mechbuf + sizeof(mechbuf) - mech_len, mech_len) == 0) found = 1; } if (!found) return send_reject (minor_status, output_token); if (init_token.mechToken != NULL) { ibuf.length = init_token.mechToken->length; ibuf.value = init_token.mechToken->data; major_status = gss_accept_sec_context(minor_status, context_handle, acceptor_cred_handle, &ibuf, input_chan_bindings, src_name, mech_type, &obuf, ret_flags, time_rec, delegated_cred_handle); if (GSS_ERROR(major_status)) { send_reject (&minor_status2, output_token); return major_status; } ot = &obuf; } ret = send_accept (&minor_status2, output_token, ot); if (ot != NULL) gss_release_buffer(&minor_status2, ot); return ret; }
static OM_uint32 GSSAPI_CALLCONV acceptor_continue (OM_uint32 * minor_status, gss_ctx_id_t * context_handle, const gss_cred_id_t acceptor_cred_handle, const gss_buffer_t input_token_buffer, const gss_channel_bindings_t input_chan_bindings, gss_name_t * src_name, gss_OID * mech_type, gss_buffer_t output_token, OM_uint32 * ret_flags, OM_uint32 * time_rec, gss_cred_id_t *delegated_cred_handle ) { OM_uint32 ret, ret2, minor; NegotiationToken nt; size_t nt_len; NegTokenResp *na; unsigned int negResult = accept_incomplete; gss_buffer_t mech_input_token = GSS_C_NO_BUFFER; gss_buffer_t mech_output_token = GSS_C_NO_BUFFER; gss_buffer_desc mech_buf; gssspnego_ctx ctx; mech_buf.value = NULL; ctx = (gssspnego_ctx)*context_handle; /* * The GSS-API encapsulation is only present on the initial * context token (negTokenInit). */ ret = decode_NegotiationToken(input_token_buffer->value, input_token_buffer->length, &nt, &nt_len); if (ret) { *minor_status = ret; return GSS_S_DEFECTIVE_TOKEN; } if (nt.element != choice_NegotiationToken_negTokenResp) { *minor_status = 0; return GSS_S_DEFECTIVE_TOKEN; } na = &nt.u.negTokenResp; if (na->negResult != NULL) { negResult = *(na->negResult); } HEIMDAL_MUTEX_lock(&ctx->ctx_id_mutex); { gss_buffer_desc ibuf, obuf; int require_mic, get_mic = 0; int require_response; heim_octet_string *mic; if (na->responseToken != NULL) { ibuf.length = na->responseToken->length; ibuf.value = na->responseToken->data; mech_input_token = &ibuf; } else { ibuf.value = NULL; ibuf.length = 0; } if (mech_input_token != GSS_C_NO_BUFFER) { if (ctx->mech_src_name != GSS_C_NO_NAME) gss_release_name(&minor, &ctx->mech_src_name); ret = gss_accept_sec_context(&minor, &ctx->negotiated_ctx_id, acceptor_cred_handle, mech_input_token, input_chan_bindings, &ctx->mech_src_name, &ctx->negotiated_mech_type, &obuf, &ctx->mech_flags, &ctx->mech_time_rec, delegated_cred_handle); if (ret == GSS_S_COMPLETE || ret == GSS_S_CONTINUE_NEEDED) { mech_output_token = &obuf; } if (ret != GSS_S_COMPLETE && ret != GSS_S_CONTINUE_NEEDED) { free_NegotiationToken(&nt); gss_mg_collect_error(ctx->negotiated_mech_type, ret, minor); send_reject (minor_status, output_token); HEIMDAL_MUTEX_unlock(&ctx->ctx_id_mutex); return ret; } if (ret == GSS_S_COMPLETE) ctx->open = 1; } else ret = GSS_S_COMPLETE; ret2 = _gss_spnego_require_mechlist_mic(minor_status, ctx, &require_mic); if (ret2) goto out; ctx->require_mic = require_mic; mic = na->mechListMIC; if (mic != NULL) require_mic = 1; if (ret == GSS_S_COMPLETE) ret = acceptor_complete(minor_status, ctx, &get_mic, &mech_buf, mech_input_token, mech_output_token, na->mechListMIC, output_token); if (ctx->mech_flags & GSS_C_DCE_STYLE) require_response = (negResult != accept_completed); else require_response = 0; /* * Check whether we need to send a result: there should be only * one accept_completed response sent in the entire negotiation */ if ((mech_output_token != GSS_C_NO_BUFFER && mech_output_token->length != 0) || (ctx->open && negResult == accept_incomplete) || require_response || get_mic) { ret2 = send_accept (minor_status, ctx, mech_output_token, 0, get_mic ? &mech_buf : NULL, output_token); if (ret2) goto out; } out: if (ret2 != GSS_S_COMPLETE) ret = ret2; if (mech_output_token != NULL) gss_release_buffer(&minor, mech_output_token); if (mech_buf.value != NULL) free(mech_buf.value); free_NegotiationToken(&nt); } if (ret == GSS_S_COMPLETE) { if (src_name != NULL && ctx->mech_src_name != NULL) { spnego_name name; name = calloc(1, sizeof(*name)); if (name) { name->mech = ctx->mech_src_name; ctx->mech_src_name = NULL; *src_name = (gss_name_t)name; } } } if (mech_type != NULL) *mech_type = ctx->negotiated_mech_type; if (ret_flags != NULL) *ret_flags = ctx->mech_flags; if (time_rec != NULL) *time_rec = ctx->mech_time_rec; if (ret == GSS_S_COMPLETE || ret == GSS_S_CONTINUE_NEEDED) { HEIMDAL_MUTEX_unlock(&ctx->ctx_id_mutex); return ret; } _gss_spnego_internal_delete_sec_context(&minor, context_handle, GSS_C_NO_BUFFER); return ret; }
static OM_uint32 GSSAPI_CALLCONV acceptor_start (OM_uint32 * minor_status, gss_ctx_id_t * context_handle, const gss_cred_id_t acceptor_cred_handle, const gss_buffer_t input_token_buffer, const gss_channel_bindings_t input_chan_bindings, gss_name_t * src_name, gss_OID * mech_type, gss_buffer_t output_token, OM_uint32 * ret_flags, OM_uint32 * time_rec, gss_cred_id_t *delegated_cred_handle ) { OM_uint32 ret, junk; NegotiationToken nt; size_t nt_len; NegTokenInit *ni; int i; gss_buffer_desc data; gss_buffer_t mech_input_token = GSS_C_NO_BUFFER; gss_buffer_desc mech_output_token; gss_buffer_desc mech_buf; gss_OID preferred_mech_type = GSS_C_NO_OID; gssspnego_ctx ctx; int get_mic = 0; int first_ok = 0; mech_output_token.value = NULL; mech_output_token.length = 0; mech_buf.value = NULL; if (input_token_buffer->length == 0) return send_supported_mechs (minor_status, output_token); ret = _gss_spnego_alloc_sec_context(minor_status, context_handle); if (ret != GSS_S_COMPLETE) return ret; ctx = (gssspnego_ctx)*context_handle; /* * The GSS-API encapsulation is only present on the initial * context token (negTokenInit). */ ret = gss_decapsulate_token (input_token_buffer, GSS_SPNEGO_MECHANISM, &data); if (ret) return ret; ret = decode_NegotiationToken(data.value, data.length, &nt, &nt_len); gss_release_buffer(minor_status, &data); if (ret) { *minor_status = ret; return GSS_S_DEFECTIVE_TOKEN; } if (nt.element != choice_NegotiationToken_negTokenInit) { *minor_status = 0; return GSS_S_DEFECTIVE_TOKEN; } ni = &nt.u.negTokenInit; if (ni->mechTypes.len < 1) { free_NegotiationToken(&nt); *minor_status = 0; return GSS_S_DEFECTIVE_TOKEN; } HEIMDAL_MUTEX_lock(&ctx->ctx_id_mutex); ret = copy_MechTypeList(&ni->mechTypes, &ctx->initiator_mech_types); if (ret) { HEIMDAL_MUTEX_unlock(&ctx->ctx_id_mutex); free_NegotiationToken(&nt); *minor_status = ret; return GSS_S_FAILURE; } /* * First we try the opportunistic token if we have support for it, * don't try to verify we have credential for the token, * gss_accept_sec_context() will (hopefully) tell us that. * If that failes, */ ret = select_mech(minor_status, &ni->mechTypes.val[0], 0, &preferred_mech_type); if (ret == 0 && ni->mechToken != NULL) { gss_buffer_desc ibuf; ibuf.length = ni->mechToken->length; ibuf.value = ni->mechToken->data; mech_input_token = &ibuf; if (ctx->mech_src_name != GSS_C_NO_NAME) gss_release_name(&junk, &ctx->mech_src_name); ret = gss_accept_sec_context(minor_status, &ctx->negotiated_ctx_id, acceptor_cred_handle, mech_input_token, input_chan_bindings, &ctx->mech_src_name, &ctx->negotiated_mech_type, &mech_output_token, &ctx->mech_flags, &ctx->mech_time_rec, delegated_cred_handle); if (ret == GSS_S_COMPLETE || ret == GSS_S_CONTINUE_NEEDED) { ctx->preferred_mech_type = preferred_mech_type; if (ret == GSS_S_COMPLETE) ctx->open = 1; ret = acceptor_complete(minor_status, ctx, &get_mic, &mech_buf, mech_input_token, &mech_output_token, ni->mechListMIC, output_token); if (ret != GSS_S_COMPLETE) goto out; first_ok = 1; } else { gss_mg_collect_error(preferred_mech_type, ret, *minor_status); } } /* * If opportunistic token failed, lets try the other mechs. */ if (!first_ok && ni->mechToken != NULL) { preferred_mech_type = GSS_C_NO_OID; /* Call glue layer to find first mech we support */ for (i = 1; i < ni->mechTypes.len; ++i) { ret = select_mech(minor_status, &ni->mechTypes.val[i], 1, &preferred_mech_type); if (ret == 0) break; } if (preferred_mech_type == GSS_C_NO_OID) { HEIMDAL_MUTEX_unlock(&ctx->ctx_id_mutex); free_NegotiationToken(&nt); return ret; } ctx->preferred_mech_type = preferred_mech_type; } /* * The initial token always have a response */ ret = send_accept (minor_status, ctx, &mech_output_token, 1, get_mic ? &mech_buf : NULL, output_token); if (ret) goto out; out: if (mech_output_token.value != NULL) gss_release_buffer(&junk, &mech_output_token); if (mech_buf.value != NULL) { free(mech_buf.value); mech_buf.value = NULL; } free_NegotiationToken(&nt); if (ret == GSS_S_COMPLETE) { if (src_name != NULL && ctx->mech_src_name != NULL) { spnego_name name; name = calloc(1, sizeof(*name)); if (name) { name->mech = ctx->mech_src_name; ctx->mech_src_name = NULL; *src_name = (gss_name_t)name; } } } if (mech_type != NULL) *mech_type = ctx->negotiated_mech_type; if (ret_flags != NULL) *ret_flags = ctx->mech_flags; if (time_rec != NULL) *time_rec = ctx->mech_time_rec; if (ret == GSS_S_COMPLETE || ret == GSS_S_CONTINUE_NEEDED) { HEIMDAL_MUTEX_unlock(&ctx->ctx_id_mutex); return ret; } _gss_spnego_internal_delete_sec_context(&junk, context_handle, GSS_C_NO_BUFFER); return ret; }
static void request_respond(struct sockaddr *from, int fromlen, int length, int fd) { CARD16 displayNumber; ARRAY16 connectionTypes; ARRAYofARRAY8 connectionAddresses; ARRAY8 authenticationName; ARRAY8 authenticationData; ARRAYofARRAY8 authorizationNames; ARRAY8 manufacturerDisplayID; ARRAY8Ptr reason = 0; int expectlen; int i, j; struct protoDisplay *pdpy; ARRAY8 authorizationName, authorizationData; ARRAY8Ptr connectionAddress; Debug("<request> respond %d\n", length); connectionTypes.data = 0; connectionAddresses.data = 0; authenticationName.data = 0; authenticationData.data = 0; authorizationNames.data = 0; authorizationName.length = 0; authorizationData.length = 0; manufacturerDisplayID.data = 0; if(XdmcpReadCARD16(&buffer, &displayNumber) && XdmcpReadARRAY16(&buffer, &connectionTypes) && XdmcpReadARRAYofARRAY8(&buffer, &connectionAddresses) && XdmcpReadARRAY8(&buffer, &authenticationName) && XdmcpReadARRAY8(&buffer, &authenticationData) && XdmcpReadARRAYofARRAY8(&buffer, &authorizationNames) && XdmcpReadARRAY8(&buffer, &manufacturerDisplayID)) { expectlen = 0; expectlen += 2; /* displayNumber */ expectlen += 1 + 2 * connectionTypes.length; /* connectionTypes */ expectlen += 1; /* connectionAddresses */ for(i = 0; i < (int)connectionAddresses.length; i++) expectlen += 2 + connectionAddresses.data[i].length; expectlen += 2 + authenticationName.length; /* authenticationName */ expectlen += 2 + authenticationData.length; /* authenticationData */ expectlen += 1; /* authoriationNames */ for(i = 0; i < (int)authorizationNames.length; i++) expectlen += 2 + authorizationNames.data[i].length; expectlen += 2 + manufacturerDisplayID.length; /* displayID */ if(expectlen != length) { Debug("<request> length error got %d expect %d\n", length, expectlen); goto abort; } if(connectionTypes.length == 0 || connectionAddresses.length != connectionTypes.length) { reason = &noValidAddr; pdpy = 0; goto decline; } pdpy = FindProtoDisplay((XdmcpNetaddr)from, fromlen, displayNumber); if(!pdpy) { /* Check this Display against the Manager's policy */ reason = Accept(from, fromlen, displayNumber); if(reason) goto decline; /* Check the Display's stream services against Manager's policy */ i = SelectConnectionTypeIndex(&connectionTypes, &connectionAddresses); if(i < 0) { reason = &noValidAddr; goto decline; } /* The Manager considers this a new session */ connectionAddress = &connectionAddresses.data[i]; pdpy = NewProtoDisplay((XdmcpNetaddr)from, fromlen, displayNumber, connectionTypes.data[i], connectionAddress, NextSessionID()); Debug("NewProtoDisplay %p\n", pdpy); if(!pdpy) { reason = &outOfMemory; goto decline; } } if(authorizationNames.length == 0) j = 0; else j = SelectAuthorizationTypeIndex(&authenticationName, &authorizationNames); if(j < 0) { reason = &noValidAuth; goto decline; } if(!CheckAuthentication(pdpy, &manufacturerDisplayID, &authenticationName, &authenticationData)) { reason = &noAuthentic; goto decline; } if(j < (int)authorizationNames.length) { Xauth *auth; SetProtoDisplayAuthorization(pdpy, (unsigned short)authorizationNames.data[j].length, (char *)authorizationNames.data[j].data); auth = pdpy->xdmcpAuthorization; if(!auth) auth = pdpy->fileAuthorization; if(auth) { authorizationName.length = auth->name_length; authorizationName.data = (CARD8Ptr)auth->name; authorizationData.length = auth->data_length; authorizationData.data = (CARD8Ptr)auth->data; } } if(pdpy) { send_accept(from, fromlen, pdpy->sessionID, &authenticationName, &authenticationData, &authorizationName, &authorizationData, fd); } else { decline: send_decline(from, fromlen, &authenticationName, &authenticationData, reason, fd); if(pdpy) DisposeProtoDisplay(pdpy); } } abort: XdmcpDisposeARRAY16(&connectionTypes); XdmcpDisposeARRAYofARRAY8(&connectionAddresses); XdmcpDisposeARRAY8(&authenticationName); XdmcpDisposeARRAY8(&authenticationData); XdmcpDisposeARRAYofARRAY8(&authorizationNames); XdmcpDisposeARRAY8(&manufacturerDisplayID); }