void test(int argc, char *argv[]) { const char *hostname; const char *service = "HTTP"; gss_buffer_desc input_token; gss_buffer_desc output_token; gss_buffer_desc name; char *ccname = NULL; gss_ctx_id_t ctx = GSS_C_NO_CONTEXT; gss_ctx_id_t ctx_init = GSS_C_NO_CONTEXT; memset(&input_token, 0, sizeof(input_token)); memset(&output_token, 0, sizeof(output_token)); memset(&name, 0, sizeof(name)); if (argc != 2) return; hostname = argv[1]; init_user(&ctx_init, service, hostname, NULL, &output_token); /* fwrite(output_token.value, output_token.length, 1, stdout); */ if (accept_user(&ctx, &output_token, &input_token, &name, &ccname) == OK) { fprintf(stderr, "User authenticated\r\n"); } }
int main(int argc, char** argv) { if (argc != 2) { printf("usage: binary_name port\n"); return -1; } tool::net_start(); std::vector<chat::channel*> rooms; rooms.push_back(new chat::channel()); tool::acceptor acceptor(argv[1]); printf("listening on port %s\n", argv[1]); while (true) { std::shared_ptr<chat::user> user = accept_user(acceptor); rooms.at(0)->add_user(user); } tool::net_stop(); return 0; }
static int accept_sec_context(char *buf, int index, ei_x_buff *presult) { ei_x_buff result = *presult; /* {accept_sec_context, {Idx, In}} -> {ok, {Idx, Name, CCName, Out}} | {needsmore, {Idx, Out}} */ int arity; gss_buffer_desc in; gss_buffer_desc out; gss_buffer_desc name; int res; char *ccname = NULL; long idx; OM_uint32 min_stat; memset(&in, 0, sizeof(in)); memset(&out, 0, sizeof(out)); memset(&name, 0, sizeof(name)); EI(ei_decode_tuple_header(buf, &index, &arity)); EI(arity != 2); EI(ei_decode_long(buf, &index, &idx)); EI(decode_gssapi_binary(buf, &index, &in)); if (idx < 0) { idx = session_find_free(); if (idx < 0) ENCODE_ERROR("no_mem"); g_sessions[idx] = GSS_C_NO_CONTEXT; } else { if (idx < 0 || idx >= MAX_SESSIONS || !g_sessions[idx]) ENCODE_ERROR("bad_instance"); } res = accept_user(&g_sessions[idx], &in, &out, &name, &ccname); if (!GSS_ERROR(res)) { if (res & GSS_S_CONTINUE_NEEDED) { EI(ei_x_encode_atom(&result, "needsmore") || ei_x_encode_tuple_header(&result, 2) || ei_x_encode_long(&result, idx) || ei_x_encode_binary(&result, out.value, out.length) ); } else { const char *ret_ccname = ccname; if (!ret_ccname) ret_ccname = ""; EI(ei_x_encode_atom(&result, "ok") || ei_x_encode_tuple_header(&result, 4) || ei_x_encode_long(&result, idx) || ei_x_encode_string_len(&result, name.value, name.length) || ei_x_encode_string(&result, ret_ccname) || ei_x_encode_binary(&result, out.value, out.length) ); } } else { EI(ei_x_encode_atom(&result, "error") || ei_x_encode_atom(&result, "unauthorized")); } error: if (ccname) free(ccname); if (in.value) gss_release_buffer(&min_stat, &in); if (out.value) gss_release_buffer(&min_stat, &out); if (name.value) gss_release_buffer(&min_stat, &name); *presult = result; return 0; }
/* * Parses a SMTP command sent in the given client socket. */ static void parse_smtp_command(socket_t socket, delivery_status_t* delst, const char* cmd, size_t cmd_len) { char base_cmd[5]; size_t i, field_begin; const char* field; /* smtp commands always are always four characters long, so if a shorter * command is found, complain a bit. */ if (cmd_len < 4) { send_string(socket, "500 What the hell are you smoking? SMTP commands are not that short!\r\n"); return; } /* copy the base command string from the command code and convert it to * lowercase characters. */ base_cmd[0] = tolower(cmd[0]); base_cmd[1] = tolower(cmd[1]); base_cmd[2] = tolower(cmd[2]); base_cmd[3] = tolower(cmd[3]); base_cmd[4] = 0; /* find the beginning of the field data, ignoring what is in between */ field_begin = 0; if (cmd[4] == ' ') { for (i=5; i<cmd_len; i++) if (cmd[i] == ':') { field_begin = i + 1; break; } } field = field_begin ? (cmd + field_begin) : NULL; /* now let's check the command */ if (!strcmp(base_cmd, "quit")) { /* QUIT issued, done and exit */ goto done; } if (!strcmp(base_cmd, "helo")) { /* HELO issued, respond with a greeting */ send_string(socket, "250 Hi to you too!\r\n"); goto done; } if (!strcmp(base_cmd, "turn")) { /* TURN issued, refuse to turn */ send_string(socket, "502 Not today honey\r\n"); goto done; } if (!strcmp(base_cmd, "noop")) { /* NOOP issued, do nothing */ send_string(socket, "250 Ok\r\n"); goto done; } if (!strcmp(base_cmd, "rset")) { /* RSET issued, let's forget what we were doing */ delst_init(delst); send_string(socket, "250 Ok\r\n"); goto done; } if (!strcmp(base_cmd, "mail")) { /* MAIL issued, let's check it and begin a new mail delivery */ if (!field || !field[0]) { /* no field data, complain */ send_string(socket, "501 Nice try but you forgot to tell me who you are\r\n"); goto done; } /* currently we don't care from where the data came but anyway */ delst_init(delst); delst->from = strdup(field); send_string(socket, "250 Ok\r\n"); goto done; } if (!strcmp(base_cmd, "rcpt")) { /* RCPT issued, let's check it and add the recipients to delst */ process_rcpt(socket, delst, field); goto done; } if (!strcmp(base_cmd, "vrfy")) { /* VRFY issued, let's check the username */ if (accept_user(field)) { /* user is known, compose the reply */ const char* domain = script_get_var("domain", "localhost"); char* full = malloc(strlen(field) + strlen(domain) + 16); if (!full) { /* out of memory, abort */ send_string(socket, "451 I've ran out of memory, oh no!\r\n"); goto done; } sprintf(full, "250 %s@%s\r\n", field, domain); send_string(socket, full); free(full); } else { /* unknown user, but let's assume its ok */ send_string(socket, "252 I couldn't find the user around, but anyway we're all friends here aren't we?\r\n"); } goto done; } if (!strcmp(base_cmd, "data")) { /* DATA issued, let's gather said data! */ gather_data(socket, delst); goto done; } send_string(socket, "502 I haven't been bothered yet to implement this command, sorry...\r\n"); /* common release code */ done: ; }
/* * Process the RCPT field. This scans the field for the user name. The expected * format for the field is "<"["@"<domain>":"]<username>"@"<domain>">". Only * the username is used, the rest are ignored. */ static void process_rcpt(socket_t socket, delivery_status_t* delst, const char* field) { size_t h; char* user = NULL; char* new_user; size_t user_len = 0; /* find the opening angle */ for (h=0; field[h]; h++) if (field[h] == '<') break; if (!field[h]) { /* bracket not found, complain */ send_string(socket, "553 Where is my bracket? The username is malformed!\r\n"); return; } /* skip the bracket and check for the first domain '@' symbol */ if (field[++h] == '@') { /* skip whatever follows up to the ':' symbol... */ for (; field[h]; h++) if (field[h] == ':') break; /* ... and the ':' symbol itself */ if (field[h] == ':') h++; } /* do we still have data? */ if (!field[h]) { /* nope :-( - let's complain! */ send_string(socket, "553 Where is my user? This isn't right. This is wrong!\r\n"); return; } /* we have data - let's scan the username */ for (; field[h]; h++) if (field[h] == '>' || field[h] == '@') { /* end of interesting data, let's stop */ break; } else { /* add char in username */ new_user = realloc(user, user_len + 1); if (!new_user) { send_string(socket, "451 I've ran out of memory. I don't know you.\r\n"); free(user); return; } user = new_user; user[user_len++] = field[h]; } /* add terminator in username */ new_user = realloc(user, user_len + 1); if (!new_user) { send_string(socket, "451 Just while i was doing fine, i forgot who you are.\r\n"); free(user); return; } user = new_user; user[user_len] = 0; /* check if the user string is valid (ie. not empty) */ if (!user[0]) { send_string(socket, "553 I need a user. A USER! Do you understand me?!\r\n"); free(user); return; } /* check if the user is acceptable */ if (!accept_user(user)) { /* ...no, this user is not acceptable */ send_string(socket, "550 There is nobody named like this here.\r\n"); free(user); return; } /* all fine, add the user to the delivery structure */ delst_add_to(delst, user); free(user); send_string(socket, "250 Ok\r\n"); }