int auth_onoff(char *type, int on) { int i, mask = -1; Authenticator *ap; if (!strcasecmp(type, "?") || !strcasecmp(type, "help")) { printf("auth %s 'type'\n", on ? "enable" : "disable"); printf("Where 'type' is one of:\n"); printf("\t%s\n", AUTHTYPE_NAME(0)); mask = 0; for (ap = authenticators; ap->type; ap++) { if ((mask & (i = typemask(ap->type))) != 0) continue; mask |= i; printf("\t%s\n", AUTHTYPE_NAME(ap->type)); } return(0); } if (!getauthmask(type, &mask)) { printf("%s: invalid authentication type\n", type); return(0); } if (on) i_wont_support &= ~mask; else i_wont_support |= mask; return(1); }
void auth_disable_name(char *name) { int x; for (x = 0; x < AUTHTYPE_CNT; ++x) { if (AUTHTYPE_NAME(x) && !strcasecmp(name, AUTHTYPE_NAME(x))) { i_wont_support |= typemask(x); break; } } }
void auth_init (char *name, int server) { TN_Authenticator *ap = authenticators; Server = server; Name = name; i_support = 0; authenticated = 0; authenticating = 0; while (ap->type) { if (!ap->init || (*ap->init) (ap, server)) { i_support |= typemask (ap->type); if (auth_debug_mode) printf (">>>%s: I support auth type %s (%d) %s (%d)\r\n", Name, AUTHTYPE_NAME_OK (ap->type) ? AUTHTYPE_NAME (ap->type) : "unknown", ap->type, ap->way & AUTH_HOW_MASK & AUTH_HOW_MUTUAL ? "MUTUAL" : "ONEWAY", ap->way); } else if (auth_debug_mode) printf (">>>%s: Init failed: auth type %d %d\r\n", Name, ap->type, ap->way); ++ap; } }
int getauthmask(char *type, int *maskp) { int x; if (AUTHTYPE_NAME(0) && !strcasecmp(type, AUTHTYPE_NAME(0))) { *maskp = -1; return(1); } for (x = 1; x < AUTHTYPE_CNT; ++x) { if (AUTHTYPE_NAME(x) && !strcasecmp(type, AUTHTYPE_NAME(x))) { *maskp = typemask(x); return(1); } } return(0); }
int auth_status(void) { Authenticator *ap; int i, mask; if (i_wont_support == -1) printf("Authentication disabled\n"); else printf("Authentication enabled\n"); mask = 0; for (ap = authenticators; ap->type; ap++) { if ((mask & (i = typemask(ap->type))) != 0) continue; mask |= i; printf("%s: %s\n", AUTHTYPE_NAME(ap->type), (i_wont_support & typemask(ap->type)) ? "disabled" : "enabled"); } return(1); }
/* int length; length of suboption data */ void printsub (char direction, unsigned char *pointer, int length) { register int i; extern int want_status_response; #if defined AUTHENTICATION || defined ENCRYPTION char buf[512]; #endif if (showoptions || direction == 0 || (want_status_response && (pointer[0] == TELOPT_STATUS))) { if (direction) { fprintf (NetTrace, "%s IAC SB ", (direction == '<') ? "RCVD" : "SENT"); if (length >= 3) { register int j; i = pointer[length - 2]; j = pointer[length - 1]; if (i != IAC || j != SE) { fprintf (NetTrace, "(terminated by "); if (TELOPT_OK (i)) fprintf (NetTrace, "%s ", TELOPT (i)); else if (TELCMD_OK (i)) fprintf (NetTrace, "%s ", TELCMD (i)); else fprintf (NetTrace, "%d ", i); if (TELOPT_OK (j)) fprintf (NetTrace, "%s", TELOPT (j)); else if (TELCMD_OK (j)) fprintf (NetTrace, "%s", TELCMD (j)); else fprintf (NetTrace, "%d", j); fprintf (NetTrace, ", not IAC SE!) "); } } length -= 2; } if (length < 1) { fprintf (NetTrace, "(Empty suboption??\?)"); if (NetTrace == stdout) fflush (NetTrace); return; } switch (pointer[0]) { case TELOPT_TTYPE: fprintf (NetTrace, "TERMINAL-TYPE "); switch (pointer[1]) { case TELQUAL_IS: fprintf (NetTrace, "IS \"%.*s\"", length - 2, (char *) pointer + 2); break; case TELQUAL_SEND: fprintf (NetTrace, "SEND"); break; default: fprintf (NetTrace, "- unknown qualifier %d (0x%x).", pointer[1], pointer[1]); } break; case TELOPT_TSPEED: fprintf (NetTrace, "TERMINAL-SPEED"); if (length < 2) { fprintf (NetTrace, " (empty suboption??\?)"); break; } switch (pointer[1]) { case TELQUAL_IS: fprintf (NetTrace, " IS "); fprintf (NetTrace, "%.*s", length - 2, (char *) pointer + 2); break; default: if (pointer[1] == 1) fprintf (NetTrace, " SEND"); else fprintf (NetTrace, " %d (unknown)", pointer[1]); for (i = 2; i < length; i++) fprintf (NetTrace, " ?%d?", pointer[i]); break; } break; case TELOPT_LFLOW: fprintf (NetTrace, "TOGGLE-FLOW-CONTROL"); if (length < 2) { fprintf (NetTrace, " (empty suboption??\?)"); break; } switch (pointer[1]) { case LFLOW_OFF: fprintf (NetTrace, " OFF"); break; case LFLOW_ON: fprintf (NetTrace, " ON"); break; case LFLOW_RESTART_ANY: fprintf (NetTrace, " RESTART-ANY"); break; case LFLOW_RESTART_XON: fprintf (NetTrace, " RESTART-XON"); break; default: fprintf (NetTrace, " %d (unknown)", pointer[1]); } for (i = 2; i < length; i++) fprintf (NetTrace, " ?%d?", pointer[i]); break; case TELOPT_NAWS: fprintf (NetTrace, "NAWS"); if (length < 2) { fprintf (NetTrace, " (empty suboption??\?)"); break; } if (length == 2) { fprintf (NetTrace, " ?%d?", pointer[1]); break; } fprintf (NetTrace, " %d %d (%d)", pointer[1], pointer[2], (int) ((((unsigned int) pointer[1]) << 8) | ((unsigned int) pointer[2]))); if (length == 4) { fprintf (NetTrace, " ?%d?", pointer[3]); break; } fprintf (NetTrace, " %d %d (%d)", pointer[3], pointer[4], (int) ((((unsigned int) pointer[3]) << 8) | ((unsigned int) pointer[4]))); for (i = 5; i < length; i++) fprintf (NetTrace, " ?%d?", pointer[i]); break; #if defined AUTHENTICATION case TELOPT_AUTHENTICATION: fprintf (NetTrace, "AUTHENTICATION"); if (length < 2) { fprintf (NetTrace, " (empty suboption??\?)"); break; } switch (pointer[1]) { case TELQUAL_REPLY: case TELQUAL_IS: fprintf (NetTrace, " %s ", (pointer[1] == TELQUAL_IS) ? "IS" : "REPLY"); if (AUTHTYPE_NAME_OK (pointer[2]) && AUTHTYPE_NAME (pointer[2])) fprintf (NetTrace, "%s ", AUTHTYPE_NAME (pointer[2])); else fprintf (NetTrace, "%d ", pointer[2]); if (length < 3) { fprintf (NetTrace, "(partial suboption??\?)"); break; } fprintf (NetTrace, "%s|%s", ((pointer[3] & AUTH_WHO_MASK) == AUTH_WHO_CLIENT) ? "CLIENT" : "SERVER", ((pointer[3] & AUTH_HOW_MASK) == AUTH_HOW_MUTUAL) ? "MUTUAL" : "ONE-WAY"); auth_printsub (&pointer[1], length - 1, buf, sizeof (buf)); fprintf (NetTrace, "%s", buf); break; case TELQUAL_SEND: i = 2; fprintf (NetTrace, " SEND "); while (i < length) { if (AUTHTYPE_NAME_OK (pointer[i]) && AUTHTYPE_NAME (pointer[i])) fprintf (NetTrace, "%s ", AUTHTYPE_NAME (pointer[i])); else fprintf (NetTrace, "%d ", pointer[i]); if (++i >= length) { fprintf (NetTrace, "(partial suboption??\?)"); break; } fprintf (NetTrace, "%s|%s ", ((pointer[i] & AUTH_WHO_MASK) == AUTH_WHO_CLIENT) ? "CLIENT" : "SERVER", ((pointer[i] & AUTH_HOW_MASK) == AUTH_HOW_MUTUAL) ? "MUTUAL" : "ONE-WAY"); ++i; } break; case TELQUAL_NAME: i = 2; fprintf (NetTrace, " NAME \""); while (i < length) putc (pointer[i++], NetTrace); putc ('"', NetTrace); break; default: for (i = 2; i < length; i++) fprintf (NetTrace, " ?%d?", pointer[i]); break; } break; #endif #ifdef ENCRYPTION case TELOPT_ENCRYPT: fprintf (NetTrace, "ENCRYPT"); if (length < 2) { fprintf (NetTrace, " (empty suboption??\?)"); break; } switch (pointer[1]) { case ENCRYPT_START: fprintf (NetTrace, " START"); break; case ENCRYPT_END: fprintf (NetTrace, " END"); break; case ENCRYPT_REQSTART: fprintf (NetTrace, " REQUEST-START"); break; case ENCRYPT_REQEND: fprintf (NetTrace, " REQUEST-END"); break; case ENCRYPT_IS: case ENCRYPT_REPLY: fprintf (NetTrace, " %s ", (pointer[1] == ENCRYPT_IS) ? "IS" : "REPLY"); if (length < 3) { fprintf (NetTrace, " (partial suboption??\?)"); break; } if (ENCTYPE_NAME_OK (pointer[2]) && ENCTYPE_NAME (pointer[2])) fprintf (NetTrace, "%s ", ENCTYPE_NAME (pointer[2])); else fprintf (NetTrace, " %d (unknown)", pointer[2]); encrypt_printsub (&pointer[1], length - 1, buf, sizeof (buf)); fprintf (NetTrace, "%s", buf); break; case ENCRYPT_SUPPORT: i = 2; fprintf (NetTrace, " SUPPORT "); while (i < length) { if (ENCTYPE_NAME_OK (pointer[i]) && ENCTYPE_NAME (pointer[i])) fprintf (NetTrace, "%s ", ENCTYPE_NAME (pointer[i])); else fprintf (NetTrace, "%d ", pointer[i]); i++; } break; case ENCRYPT_ENC_KEYID: fprintf (NetTrace, " ENC_KEYID "); goto encommon; case ENCRYPT_DEC_KEYID: fprintf (NetTrace, " DEC_KEYID "); goto encommon; default: fprintf (NetTrace, " %d (unknown)", pointer[1]); encommon: for (i = 2; i < length; i++) fprintf (NetTrace, " %d", pointer[i]); break; } break; #endif /* ENCRYPTION */ case TELOPT_LINEMODE: fprintf (NetTrace, "LINEMODE "); if (length < 2) { fprintf (NetTrace, " (empty suboption??\?)"); break; } switch (pointer[1]) { case WILL: fprintf (NetTrace, "WILL "); goto common; case WONT: fprintf (NetTrace, "WONT "); goto common; case DO: fprintf (NetTrace, "DO "); goto common; case DONT: fprintf (NetTrace, "DONT "); common: if (length < 3) { fprintf (NetTrace, "(no option??\?)"); break; } switch (pointer[2]) { case LM_FORWARDMASK: fprintf (NetTrace, "Forward Mask"); for (i = 3; i < length; i++) fprintf (NetTrace, " %x", pointer[i]); break; default: fprintf (NetTrace, "%d (unknown)", pointer[2]); for (i = 3; i < length; i++) fprintf (NetTrace, " %d", pointer[i]); break; } break; case LM_SLC: fprintf (NetTrace, "SLC"); for (i = 2; i < length - 2; i += 3) { if (SLC_NAME_OK (pointer[i + SLC_FUNC])) fprintf (NetTrace, " %s", SLC_NAME (pointer[i + SLC_FUNC])); else fprintf (NetTrace, " %d", pointer[i + SLC_FUNC]); switch (pointer[i + SLC_FLAGS] & SLC_LEVELBITS) { case SLC_NOSUPPORT: fprintf (NetTrace, " NOSUPPORT"); break; case SLC_CANTCHANGE: fprintf (NetTrace, " CANTCHANGE"); break; case SLC_VARIABLE: fprintf (NetTrace, " VARIABLE"); break; case SLC_DEFAULT: fprintf (NetTrace, " DEFAULT"); break; } fprintf (NetTrace, "%s%s%s", (pointer[i + SLC_FLAGS] & SLC_ACK) ? "|ACK" : "", (pointer[i + SLC_FLAGS] & SLC_FLUSHIN) ? "|FLUSHIN" : "", (pointer[i + SLC_FLAGS] & SLC_FLUSHOUT) ? "|FLUSHOUT" : ""); if (pointer[i + SLC_FLAGS] & ~(SLC_ACK | SLC_FLUSHIN | SLC_FLUSHOUT | SLC_LEVELBITS)) fprintf (NetTrace, "(0x%x)", pointer[i + SLC_FLAGS]); fprintf (NetTrace, " %d;", pointer[i + SLC_VALUE]); if ((pointer[i + SLC_VALUE] == IAC) && (pointer[i + SLC_VALUE + 1] == IAC)) i++; } for (; i < length; i++) fprintf (NetTrace, " ?%d?", pointer[i]); break; case LM_MODE: fprintf (NetTrace, "MODE "); if (length < 3) { fprintf (NetTrace, "(no mode??\?)"); break; } { char tbuf[64]; sprintf (tbuf, "%s%s%s%s%s", pointer[2] & MODE_EDIT ? "|EDIT" : "", pointer[2] & MODE_TRAPSIG ? "|TRAPSIG" : "", pointer[2] & MODE_SOFT_TAB ? "|SOFT_TAB" : "", pointer[2] & MODE_LIT_ECHO ? "|LIT_ECHO" : "", pointer[2] & MODE_ACK ? "|ACK" : ""); fprintf (NetTrace, "%s", tbuf[1] ? &tbuf[1] : "0"); } if (pointer[2] & ~(MODE_MASK)) fprintf (NetTrace, " (0x%x)", pointer[2]); for (i = 3; i < length; i++) fprintf (NetTrace, " ?0x%x?", pointer[i]); break; default: fprintf (NetTrace, "%d (unknown)", pointer[1]); for (i = 2; i < length; i++) fprintf (NetTrace, " %d", pointer[i]); } break; case TELOPT_STATUS: { register char *cp; register int j, k; fprintf (NetTrace, "STATUS"); switch (pointer[1]) { default: if (pointer[1] == TELQUAL_SEND) fprintf (NetTrace, " SEND"); else fprintf (NetTrace, " %d (unknown)", pointer[1]); for (i = 2; i < length; i++) fprintf (NetTrace, " ?%d?", pointer[i]); break; case TELQUAL_IS: if (--want_status_response < 0) want_status_response = 0; if (NetTrace == stdout) fprintf (NetTrace, " IS\r\n"); else fprintf (NetTrace, " IS\n"); for (i = 2; i < length; i++) { switch (pointer[i]) { case DO: cp = "DO"; goto common2; case DONT: cp = "DONT"; goto common2; case WILL: cp = "WILL"; goto common2; case WONT: cp = "WONT"; goto common2; common2: i++; if (TELOPT_OK ((int) pointer[i])) fprintf (NetTrace, " %s %s", cp, TELOPT (pointer[i])); else fprintf (NetTrace, " %s %d", cp, pointer[i]); if (NetTrace == stdout) fprintf (NetTrace, "\r\n"); else fprintf (NetTrace, "\n"); break; case SB: fprintf (NetTrace, " SB "); i++; j = k = i; while (j < length) { if (pointer[j] == SE) { if (j + 1 == length) break; if (pointer[j + 1] == SE) j++; else break; } pointer[k++] = pointer[j++]; } printsub (0, &pointer[i], k - i); if (i < length) { fprintf (NetTrace, " SE"); i = j; } else i = j - 1; if (NetTrace == stdout) fprintf (NetTrace, "\r\n"); else fprintf (NetTrace, "\n"); break; default: fprintf (NetTrace, " %d", pointer[i]); break; } } break; } break; } case TELOPT_XDISPLOC: fprintf (NetTrace, "X-DISPLAY-LOCATION "); switch (pointer[1]) { case TELQUAL_IS: fprintf (NetTrace, "IS \"%.*s\"", length - 2, (char *) pointer + 2); break; case TELQUAL_SEND: fprintf (NetTrace, "SEND"); break; default: fprintf (NetTrace, "- unknown qualifier %d (0x%x).", pointer[1], pointer[1]); } break; case TELOPT_NEW_ENVIRON: fprintf (NetTrace, "NEW-ENVIRON "); #ifdef OLD_ENVIRON goto env_common1; case TELOPT_OLD_ENVIRON: fprintf (NetTrace, "OLD-ENVIRON"); env_common1: #endif switch (pointer[1]) { case TELQUAL_IS: fprintf (NetTrace, "IS "); goto env_common; case TELQUAL_SEND: fprintf (NetTrace, "SEND "); goto env_common; case TELQUAL_INFO: fprintf (NetTrace, "INFO "); env_common: { const char *quote = ""; #if defined ENV_HACK && defined OLD_ENVIRON extern int old_env_var, old_env_value; #endif for (i = 2; i < length; i++) { switch (pointer[i]) { case NEW_ENV_VALUE: #ifdef OLD_ENVIRON /* case NEW_ENV_OVAR: */ if (pointer[0] == TELOPT_OLD_ENVIRON) { # ifdef ENV_HACK if (old_env_var == OLD_ENV_VALUE) fprintf (NetTrace, "%s(VALUE) ", quote); else # endif fprintf (NetTrace, "%sVAR ", quote); } else #endif /* OLD_ENVIRON */ fprintf (NetTrace, "%sVALUE ", quote); quote = ""; break; case NEW_ENV_VAR: #ifdef OLD_ENVIRON /* case OLD_ENV_VALUE: */ if (pointer[0] == TELOPT_OLD_ENVIRON) { # ifdef ENV_HACK if (old_env_value == OLD_ENV_VAR) fprintf (NetTrace, "%s(VAR) ", quote); else # endif fprintf (NetTrace, "%sVALUE ", quote); } else #endif /* OLD_ENVIRON */ fprintf (NetTrace, "%sVAR ", quote); quote = ""; break; case ENV_ESC: fprintf (NetTrace, "%sESC ", quote); quote = ""; break; case ENV_USERVAR: fprintf (NetTrace, "%sUSERVAR ", quote); quote = ""; break; default: if (isprint (pointer[i]) && pointer[i] != '"') { if (quote[0] == '\0') { putc ('"', NetTrace); quote = "\" "; } putc (pointer[i], NetTrace); } else { fprintf (NetTrace, "%s%03o ", quote, pointer[i]); quote = ""; } break; } } if (quote[0] != '\0') putc ('"', NetTrace); break; } } break; default: if (TELOPT_OK (pointer[0])) fprintf (NetTrace, "%s (unknown)", TELOPT (pointer[0])); else fprintf (NetTrace, "%d (unknown)", pointer[0]); for (i = 1; i < length; i++) fprintf (NetTrace, " %d", pointer[i]); break; } if (direction) { if (NetTrace == stdout) fprintf (NetTrace, "\r\n"); else fprintf (NetTrace, "\n"); } if (NetTrace == stdout) fflush (NetTrace); } }
/* * This is called when an AUTH SEND is received. * It should never arrive on the server side (as only the server can * send an AUTH SEND). * You should probably respond to it if you can... * * If you want to respond to the types out of order (i.e. even * if he sends LOGIN KERBEROS and you support both, you respond * with KERBEROS instead of LOGIN (which is against what the * protocol says)) you will have to hack this code... */ void auth_send (unsigned char *data, int cnt) { TN_Authenticator *ap; static unsigned char str_none[] = { IAC, SB, TELOPT_AUTHENTICATION, TELQUAL_IS, AUTHTYPE_NULL, 0, IAC, SE }; if (Server) { if (auth_debug_mode) { printf (">>>%s: auth_send called!\r\n", Name); } return; } if (auth_debug_mode) { printf (">>>%s: auth_send got:", Name); printd (data, cnt); printf ("\r\n"); } /* * Save the data, if it is new, so that we can continue looking * at it if the authorization we try doesn't work */ if (data < _auth_send_data || data > _auth_send_data + sizeof (_auth_send_data)) { auth_send_cnt = cnt > sizeof (_auth_send_data) ? sizeof (_auth_send_data) : cnt; memmove ((void *) _auth_send_data, (void *) data, auth_send_cnt); auth_send_data = _auth_send_data; } else { /* * This is probably a no-op, but we just make sure */ auth_send_data = data; auth_send_cnt = cnt; } while ((auth_send_cnt -= 2) >= 0) { if (auth_debug_mode) printf (">>>%s: He supports %s (%d) %s (%d)\r\n", Name, AUTHTYPE_NAME_OK (auth_send_data[0]) ? AUTHTYPE_NAME (auth_send_data[0]) : "unknown", auth_send_data[0], auth_send_data[1] & AUTH_HOW_MASK & AUTH_HOW_MUTUAL ? "MUTUAL" : "ONEWAY", auth_send_data[1]); if ((i_support & ~i_wont_support) & typemask (*auth_send_data)) { ap = findauthenticator (auth_send_data[0], auth_send_data[1]); if (ap && ap->send) { if (auth_debug_mode) printf (">>>%s: Trying %s (%d) %s (%d)\r\n", Name, AUTHTYPE_NAME_OK (auth_send_data[0]) ? AUTHTYPE_NAME (auth_send_data[0]) : "unknown", auth_send_data[0], auth_send_data[1] & AUTH_HOW_MASK & AUTH_HOW_MUTUAL ? "MUTUAL" : "ONEWAY", auth_send_data[1]); if ((*ap->send) (ap)) { /* * Okay, we found one we like * and did it. * we can go home now. */ if (auth_debug_mode) printf (">>>%s: Using type %s (%d)\r\n", Name, AUTHTYPE_NAME_OK (*auth_send_data) ? AUTHTYPE_NAME (*auth_send_data) : "unknown", *auth_send_data); auth_send_data += 2; return; } } /* else * just continue on and look for the * next one if we didn't do anything. */ } auth_send_data += 2; } net_write (str_none, sizeof (str_none)); printsub ('>', &str_none[2], sizeof (str_none) - 2); if (auth_debug_mode) printf (">>>%s: Sent failure message\r\n", Name); auth_finished (0, AUTH_REJECT); # ifdef KANNAN /* * We requested strong authentication, however no mechanisms worked. * Therefore, exit on client end. */ printf ("Unable to securely authenticate user ... exit\n"); exit (EXIT_SUCCESS); # endif /* KANNAN */ }