diff --git a/crypto/dist/ssh/auth-krb4.c b/crypto/dist/ssh/auth-krb4.c new file mode 100644 index 000000000000..34aabd0142d1 --- /dev/null +++ b/crypto/dist/ssh/auth-krb4.c @@ -0,0 +1,361 @@ +/* $NetBSD: auth-krb4.c,v 1.17 2005/04/23 16:55:03 christos Exp $ */ +/* + * Copyright (c) 1999 Dug Song. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "includes.h" +RCSID("$OpenBSD: auth-krb4.c,v 1.29 2003/02/21 10:34:48 mpech Exp $"); +__RCSID("$NetBSD: auth-krb4.c,v 1.17 2005/04/23 16:55:03 christos Exp $"); + +#include "ssh.h" +#include "ssh1.h" +#include "packet.h" +#include "xmalloc.h" +#include "log.h" +#include "servconf.h" +#include "uidswap.h" +#include "auth.h" + +#ifdef AFS +#include "radix.h" +#endif + +#ifdef KRB4 +extern ServerOptions options; + +static int +krb4_init(void *context) +{ + Authctxt *authctxt = (Authctxt *)context; + const char *tkt_root = TKT_ROOT; + struct stat st; + int fd; + + if (!authctxt->krb4_ticket_file) { + /* Set unique ticket string manually since we're still root. */ + authctxt->krb4_ticket_file = xmalloc(MAXPATHLEN); +#ifdef AFS + if (lstat("/ticket", &st) != -1) + tkt_root = "/ticket/"; +#endif /* AFS */ + snprintf(authctxt->krb4_ticket_file, MAXPATHLEN, "%s%u_%ld", + tkt_root, authctxt->pw->pw_uid, (long)getpid()); + krb_set_tkt_string(authctxt->krb4_ticket_file); + } + /* Try to create our ticket file. */ + if ((fd = mkstemp(authctxt->krb4_ticket_file)) != -1) { + close(fd); + return (1); + } + /* Ticket file exists - make sure user owns it (just passed ticket). */ + if (lstat(authctxt->krb4_ticket_file, &st) != -1) { + if (st.st_mode == (S_IFREG | S_IRUSR | S_IWUSR) && + st.st_uid == authctxt->pw->pw_uid) + return (1); + } + /* Failure - cancel cleanup function, leaving ticket for inspection. */ + logit("WARNING: bad ticket file %s", authctxt->krb4_ticket_file); + + xfree(authctxt->krb4_ticket_file); + authctxt->krb4_ticket_file = NULL; + + return (0); +} + +/* + * try krb4 authentication, + * return 1 on success, 0 on failure, -1 if krb4 is not available + */ +int +auth_krb4_password(Authctxt *authctxt, const char *password) +{ + AUTH_DAT adata; + KTEXT_ST tkt; + struct hostent *hp; + struct passwd *pw; + char localhost[MAXHOSTNAMELEN], phost[INST_SZ], realm[REALM_SZ]; + u_int32_t faddr; + int r; + + if ((pw = authctxt->pw) == NULL) + return (0); + + /* + * Try Kerberos password authentication only for non-root + * users and only if Kerberos is installed. + */ + if (pw->pw_uid != 0 && krb_get_lrealm(realm, 1) == KSUCCESS) { + /* Set up our ticket file. */ + if (!krb4_init(authctxt)) { + logit("Couldn't initialize Kerberos ticket file for %s!", + pw->pw_name); + goto failure; + } + /* Try to get TGT using our password. */ + r = krb_get_pw_in_tkt((char *) pw->pw_name, "", realm, + "krbtgt", realm, DEFAULT_TKT_LIFE, (char *)password); + if (r != INTK_OK) { + debug("Kerberos v4 password authentication for %s " + "failed: %s", pw->pw_name, krb_err_txt[r]); + goto failure; + } + /* Successful authentication. */ + chown(tkt_string(), pw->pw_uid, pw->pw_gid); + + /* + * Now that we have a TGT, try to get a local + * "rcmd" ticket to ensure that we are not talking + * to a bogus Kerberos server. + */ + gethostname(localhost, sizeof(localhost)); + strlcpy(phost, (char *)krb_get_phost(localhost), + sizeof(phost)); + r = krb_mk_req(&tkt, KRB4_SERVICE_NAME, phost, realm, 33); + + if (r == KSUCCESS) { + if ((hp = gethostbyname(localhost)) == NULL) { + logit("Couldn't get local host address!"); + goto failure; + } + memmove((void *)&faddr, (void *)hp->h_addr, + sizeof(faddr)); + + /* Verify our "rcmd" ticket. */ + r = krb_rd_req(&tkt, KRB4_SERVICE_NAME, phost, + faddr, &adata, ""); + if (r == RD_AP_UNDEC) { + /* + * Probably didn't have a srvtab on + * localhost. Disallow login. + */ + logit("Kerberos v4 TGT for %s unverifiable, " + "no srvtab installed? krb_rd_req: %s", + pw->pw_name, krb_err_txt[r]); + goto failure; + } else if (r != KSUCCESS) { + logit("Kerberos v4 %s ticket unverifiable: %s", + KRB4_SERVICE_NAME, krb_err_txt[r]); + goto failure; + } + } else if (r == KDC_PR_UNKNOWN) { + /* + * Disallow login if no rcmd service exists, and + * log the error. + */ + logit("Kerberos v4 TGT for %s unverifiable: %s; %s.%s " + "not registered, or srvtab is wrong?", pw->pw_name, + krb_err_txt[r], KRB4_SERVICE_NAME, phost); + goto failure; + } else { + /* + * TGT is bad, forget it. Possibly spoofed! + */ + debug("WARNING: Kerberos v4 TGT possibly spoofed " + "for %s: %s", pw->pw_name, krb_err_txt[r]); + goto failure; + } + /* Authentication succeeded. */ + return (1); + } else + /* Logging in as root or no local Kerberos realm. */ + debug("Unable to authenticate to Kerberos."); + + failure: + krb4_cleanup_proc(authctxt); + + if (!options.kerberos_or_local_passwd) + return (0); + + /* Fall back to ordinary passwd authentication. */ + return (-1); +} + +void +krb4_cleanup_proc(void *context) +{ + Authctxt *authctxt = (Authctxt *)context; + debug("krb4_cleanup_proc called"); + if (authctxt->krb4_ticket_file) { + (void) dest_tkt(); + xfree(authctxt->krb4_ticket_file); + authctxt->krb4_ticket_file = NULL; + } +} + +int +auth_krb4(Authctxt *authctxt, KTEXT auth, char **client, KTEXT reply) +{ + AUTH_DAT adat = {0}; + Key_schedule schedule; + struct sockaddr_in local, foreign; + char instance[INST_SZ]; + socklen_t slen; + u_int cksum; + int r, s; + + s = packet_get_connection_in(); + + slen = sizeof(local); + memset(&local, 0, sizeof(local)); + if (getsockname(s, (struct sockaddr *) & local, &slen) < 0) + debug("getsockname failed: %.100s", strerror(errno)); + slen = sizeof(foreign); + memset(&foreign, 0, sizeof(foreign)); + if (getpeername(s, (struct sockaddr *) & foreign, &slen) < 0) { + debug("getpeername failed: %.100s", strerror(errno)); + cleanup_exit(255); + } + instance[0] = '*'; + instance[1] = 0; + + /* Get the encrypted request, challenge, and session key. */ + if ((r = krb_rd_req(auth, KRB4_SERVICE_NAME, instance, + 0, &adat, ""))) { + debug("Kerberos v4 krb_rd_req: %.100s", krb_err_txt[r]); + return (0); + } + des_key_sched((des_cblock *) adat.session, schedule); + + *client = xmalloc(MAX_K_NAME_SZ); + (void) snprintf(*client, MAX_K_NAME_SZ, "%s%s%s@%s", adat.pname, + *adat.pinst ? "." : "", adat.pinst, adat.prealm); + + /* Check ~/.klogin authorization now. */ + if (kuserok(&adat, authctxt->user) != KSUCCESS) { + logit("Kerberos v4 .klogin authorization failed for %s to " + "account %s", *client, authctxt->user); + xfree(*client); + *client = NULL; + return (0); + } + /* Increment the checksum, and return it encrypted with the + session key. */ + cksum = adat.checksum + 1; + cksum = htonl(cksum); + + /* If we can't successfully encrypt the checksum, we send back an + empty message, admitting our failure. */ + if ((r = krb_mk_priv((u_char *) & cksum, reply->dat, sizeof(cksum) + 1, + schedule, &adat.session, &local, &foreign)) < 0) { + debug("Kerberos v4 mk_priv: (%d) %s", r, krb_err_txt[r]); + reply->dat[0] = 0; + reply->length = 0; + } else + reply->length = r; + + /* Clear session key. */ + memset(&adat.session, 0, sizeof(adat.session)); + return (1); +} +#endif /* KRB4 */ + +#ifdef AFS +int +auth_krb4_tgt(Authctxt *authctxt, const char *string) +{ + CREDENTIALS creds; + struct passwd *pw; + + if ((pw = authctxt->pw) == NULL) + goto failure; + + temporarily_use_uid(pw); + + if (!radix_to_creds(string, &creds)) { + logit("Protocol error decoding Kerberos v4 TGT"); + goto failure; + } + if (strncmp(creds.service, "", 1) == 0) /* backward compatibility */ + strlcpy(creds.service, "krbtgt", sizeof creds.service); + + if (strcmp(creds.service, "krbtgt")) { + logit("Kerberos v4 TGT (%s%s%s@%s) rejected for %s", + creds.pname, creds.pinst[0] ? "." : "", creds.pinst, + creds.realm, pw->pw_name); + goto failure; + } + if (!krb4_init(authctxt)) + goto failure; + + if (in_tkt(creds.pname, creds.pinst) != KSUCCESS) + goto failure; + + if (save_credentials(creds.service, creds.instance, creds.realm, + creds.session, creds.lifetime, creds.kvno, &creds.ticket_st, + creds.issue_date) != KSUCCESS) { + debug("Kerberos v4 TGT refused: couldn't save credentials"); + goto failure; + } + /* Successful authentication, passed all checks. */ + chown(tkt_string(), pw->pw_uid, pw->pw_gid); + + debug("Kerberos v4 TGT accepted (%s%s%s@%s)", + creds.pname, creds.pinst[0] ? "." : "", creds.pinst, creds.realm); + memset(&creds, 0, sizeof(creds)); + + restore_uid(); + + return (1); + + failure: + krb4_cleanup_proc(authctxt); + memset(&creds, 0, sizeof(creds)); + restore_uid(); + + return (0); +} + +int +auth_afs_token(Authctxt *authctxt, const char *token_string) +{ + CREDENTIALS creds; + struct passwd *pw; + uid_t uid; + + if ((pw = authctxt->pw) == NULL) + return (0); + + if (!radix_to_creds(token_string, &creds)) { + logit("Protocol error decoding AFS token"); + return (0); + } + if (strncmp(creds.service, "", 1) == 0) /* backward compatibility */ + strlcpy(creds.service, "afs", sizeof creds.service); + + if (strncmp(creds.pname, "AFS ID ", 7) == 0) + uid = atoi(creds.pname + 7); + else + uid = pw->pw_uid; + + if (kafs_settoken(creds.realm, uid, &creds)) { + logit("AFS token (%s@%s) rejected for %s", + creds.pname, creds.realm, pw->pw_name); + memset(&creds, 0, sizeof(creds)); + return (0); + } + debug("AFS token accepted (%s@%s)", creds.pname, creds.realm); + memset(&creds, 0, sizeof(creds)); + + return (1); +} +#endif /* AFS */ diff --git a/crypto/dist/ssh/auth2-krb5.c b/crypto/dist/ssh/auth2-krb5.c new file mode 100644 index 000000000000..78779464ef86 --- /dev/null +++ b/crypto/dist/ssh/auth2-krb5.c @@ -0,0 +1,70 @@ +/* $NetBSD: auth2-krb5.c,v 1.7 2005/04/23 16:55:03 christos Exp $ */ +/* + * Copyright (c) 2003 Markus Friedl. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "includes.h" +RCSID("$OpenBSD: auth2-krb5.c,v 1.2 2003/05/15 14:09:21 markus Exp $"); +__RCSID("$NetBSD: auth2-krb5.c,v 1.7 2005/04/23 16:55:03 christos Exp $"); + +#include + +#include "ssh2.h" +#include "xmalloc.h" +#include "packet.h" +#include "log.h" +#include "auth.h" +#include "monitor_wrap.h" +#include "servconf.h" + +/* import */ +extern ServerOptions options; + +static int +userauth_kerberos(Authctxt *authctxt) +{ + krb5_data tkt, reply; + u_int dlen; + char *client = NULL; + int authenticated = 0; + + tkt.data = packet_get_string(&dlen); + tkt.length = dlen; + packet_check_eom(); + + if (PRIVSEP(auth_krb5(authctxt, &tkt, &client, &reply))) { + authenticated = 1; + if (reply.length) + xfree(reply.data); + } + if (client) + xfree(client); + xfree(tkt.data); + return (authenticated); +} + +Authmethod method_kerberos = { + "kerberos-2@ssh.com", + userauth_kerberos, + &options.kerberos_authentication +}; diff --git a/crypto/dist/ssh/moduli.5 b/crypto/dist/ssh/moduli.5 new file mode 100644 index 000000000000..a30ddd676ee1 --- /dev/null +++ b/crypto/dist/ssh/moduli.5 @@ -0,0 +1,165 @@ +.\" $NetBSD: moduli.5,v 1.13 2005/04/23 16:55:03 christos Exp $ +.\" $OpenBSD: moduli.5,v 1.7 2003/03/06 20:48:35 jmc Exp $ +.\" +.\" Copyright 1997, 2000 William Allen Simpson +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" 3. All advertising materials mentioning features or use of this software +.\" must display the following acknowledgement: +.\" This product includes software designed by William Allen Simpson. +.\" 4. The name of the author may not be used to endorse or promote products +.\" derived from this software without specific prior written permission. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR +.\" IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +.\" OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +.\" IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, +.\" INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +.\" DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +.\" THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF +.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +.\" +.\" Manual page, using -mandoc macros +.\" +.Dd February 7, 2005 +.Dt MODULI 5 +.Os +.Sh NAME +.Nm moduli +.Nd system moduli file +.Sh DESCRIPTION +The +.Pa /etc/moduli +file contains the system-wide Diffie-Hellman prime moduli for +.Xr sshd 8 . +.Pp +Each line in this file contains the following fields: +Time, Type, Tests, Tries, Size, Generator, Modulus. +The fields are separated by white space (tab or blank). +.Pp +.Fa Time : yyyymmddhhmmss . +Specifies the system time that the line was appended to the file. +The value 00000000000000 means unknown (historic). +.\"The file is sorted in ascending order. +.Pp +.Fa Type : decimal . +Specifies the internal structure of the prime modulus. +.Pp +.Bl -tag -width indent -offset indent -compact +.It 0 : +unknown; +often learned from peer during protocol operation, +and saved for later analysis. +.It 1 : +unstructured; +a common large number. +.It 2 : +safe (p = 2q + 1); +meets basic structural requirements. +.It 3 : +Schnorr. +.It 4 : +Sophie-Germaine (q = (p-1)/2); +usually generated in the process of testing safe or strong primes. +.It 5 : +strong; +useful for RSA public key generation. +.El +.Pp +.Fa Tests : decimal (bit field) . +Specifies the methods used in checking for primality. +Usually, more than one test is used. +.Pp +.Bl -tag -width indent -offset indent -compact +.It 0 : +not tested; +often learned from peer during protocol operation, +and saved for later analysis. +.It 1 : +composite; +failed one or more tests. +In this case, the highest bit specifies the test that failed. +.It 2 : +sieve; +checked for division by a range of smaller primes. +.It 4 : +Miller-Rabin. +.It 8 : +Jacobi. +.It 16 : +Elliptic Curve. +.El +.Pp +.Fa Tries : decimal . +Depends on the value of the highest valid Test bit, +where the method specified is: +.Pp +.Bl -tag -width indent -offset indent -compact +.It 0 : +not tested +(always zero). +.It 1 : +composite +(irrelevant). +.It 2 : +sieve; +number of primes sieved. +Commonly on the order of 32,000,000. +.It 4 : +Miller-Rabin; +number of M-R iterations. +Commonly on the order of 32 to 64. +.It 8 : +Jacobi; +unknown +(always zero). +.It 16 : +Elliptic Curve; +unused +(always zero). +.El +.Pp +.Fa Size : decimal . +Specifies the number of the most significant bit (0 to M). +.Pp +.Fa Generator : hex string . +Specifies the best generator for a Diffie-Hellman exchange. +0 = unknown or variable, +2, 3, 5, etc. +.Pp +.Fa Modulus : hex string . +The prime modulus. +.Pp +The file should be searched for moduli that meet the appropriate +Time, Size and Generator criteria. +When more than one meet the criteria, +the selection should be weighted toward newer moduli, +without completely disqualifying older moduli. +.Pp +Note that +.Xr sshd 8 +uses only the Size criteria and then selects a modulus at random +if more than one meet the Size criteria. +.Sh FILES +.Bl -tag -width /etc/moduli -compact +.It Pa /etc/moduli +.El +.Sh SEE ALSO +.Xr sshd 8 +.Sh HISTORY +The +.Nm +file appeared in +.Ox 2.8 +and +.Nx 1.6 . diff --git a/crypto/dist/ssh/radix.c b/crypto/dist/ssh/radix.c new file mode 100644 index 000000000000..fafe70f82298 --- /dev/null +++ b/crypto/dist/ssh/radix.c @@ -0,0 +1,160 @@ +/* $NetBSD: radix.c,v 1.17 2005/04/23 16:55:03 christos Exp $ */ +/* + * Copyright (c) 1999 Dug Song. All rights reserved. + * Copyright (c) 2002 Markus Friedl. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "includes.h" +#include "uuencode.h" + +RCSID("$OpenBSD: radix.c,v 1.22 2002/09/09 14:54:15 markus Exp $"); +__RCSID("$NetBSD: radix.c,v 1.17 2005/04/23 16:55:03 christos Exp $"); + +#ifdef AFS +#include + +#include +#include "bufaux.h" + +int +creds_to_radix(CREDENTIALS *creds, u_char *buf, size_t buflen) +{ + Buffer b; + int ret; + + buffer_init(&b); + + buffer_put_char(&b, 1); /* version */ + + buffer_append(&b, creds->service, strlen(creds->service)); + buffer_put_char(&b, '\0'); + buffer_append(&b, creds->instance, strlen(creds->instance)); + buffer_put_char(&b, '\0'); + buffer_append(&b, creds->realm, strlen(creds->realm)); + buffer_put_char(&b, '\0'); + buffer_append(&b, creds->pname, strlen(creds->pname)); + buffer_put_char(&b, '\0'); + buffer_append(&b, creds->pinst, strlen(creds->pinst)); + buffer_put_char(&b, '\0'); + + /* Null string to repeat the realm. */ + buffer_put_char(&b, '\0'); + + buffer_put_int(&b, creds->issue_date); + buffer_put_int(&b, krb_life_to_time(creds->issue_date, + creds->lifetime)); + buffer_append(&b, creds->session, sizeof(creds->session)); + buffer_put_short(&b, creds->kvno); + + /* 32 bit size + data */ + buffer_put_string(&b, creds->ticket_st.dat, creds->ticket_st.length); + + ret = uuencode(buffer_ptr(&b), buffer_len(&b), (char *)buf, buflen); + + buffer_free(&b); + return ret; +} + +#define GETSTRING(b, t, tlen) \ + do { \ + int i, found = 0; \ + for (i = 0; i < tlen; i++) { \ + if (buffer_len(b) == 0) \ + goto done; \ + t[i] = buffer_get_char(b); \ + if (t[i] == '\0') { \ + found = 1; \ + break; \ + } \ + } \ + if (!found) \ + goto done; \ + } while(0) + +int +radix_to_creds(const char *buf, CREDENTIALS *creds) +{ + Buffer b; + u_char *space; + char c, version, *p; + u_int endTime, len; + int blen, ret; + + ret = 0; + blen = strlen(buf); + + /* sanity check for size */ + if (blen > 8192) + return 0; + + buffer_init(&b); + space = buffer_append_space(&b, blen); + + /* check version and length! */ + len = uudecode(buf, space, blen); + if (len < 1) + goto done; + + version = buffer_get_char(&b); + + GETSTRING(&b, creds->service, sizeof creds->service); + GETSTRING(&b, creds->instance, sizeof creds->instance); + GETSTRING(&b, creds->realm, sizeof creds->realm); + GETSTRING(&b, creds->pname, sizeof creds->pname); + GETSTRING(&b, creds->pinst, sizeof creds->pinst); + + if (buffer_len(&b) == 0) + goto done; + + /* Ignore possibly different realm. */ + while (buffer_len(&b) > 0 && (c = buffer_get_char(&b)) != '\0') + ; + + if (buffer_len(&b) == 0) + goto done; + + creds->issue_date = buffer_get_int(&b); + + endTime = buffer_get_int(&b); + creds->lifetime = krb_time_to_life(creds->issue_date, endTime); + + len = buffer_len(&b); + if (len < sizeof(creds->session)) + goto done; + memcpy(&creds->session, buffer_ptr(&b), sizeof(creds->session)); + buffer_consume(&b, sizeof(creds->session)); + + creds->kvno = buffer_get_short(&b); + + p = buffer_get_string(&b, &len); + if (len < 0 || len > sizeof(creds->ticket_st.dat)) + goto done; + memcpy(&creds->ticket_st.dat, p, len); + creds->ticket_st.length = len; + + ret = 1; +done: + buffer_free(&b); + return ret; +} +#endif /* AFS */ diff --git a/crypto/dist/ssh/radix.h b/crypto/dist/ssh/radix.h new file mode 100644 index 000000000000..73e3e5b76300 --- /dev/null +++ b/crypto/dist/ssh/radix.h @@ -0,0 +1,29 @@ +/* $NetBSD: radix.h,v 1.9 2005/04/23 16:55:03 christos Exp $ */ +/* $OpenBSD: radix.h,v 1.4 2001/06/26 17:27:24 markus Exp $ */ + +/* + * Copyright (c) 1999 Dug Song. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +int creds_to_radix(CREDENTIALS *, u_char *, size_t); +int radix_to_creds(const char *, CREDENTIALS *); diff --git a/crypto/dist/ssh/readpassphrase.3 b/crypto/dist/ssh/readpassphrase.3 new file mode 100644 index 000000000000..de310e135a03 --- /dev/null +++ b/crypto/dist/ssh/readpassphrase.3 @@ -0,0 +1,118 @@ +.\" $NetBSD: readpassphrase.3,v 1.6 2005/04/23 16:55:03 christos Exp $ +.\" $OpenBSD: readpassphrase.3,v 1.3 2001/08/06 10:42:25 mpech Exp $ +.\" +.\" Copyright (c) 2000 Todd C. Miller +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" 3. The name of the author may not be used to endorse or promote products +.\" derived from this software without specific prior written permission. +.\" +.\" THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, +.\" INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY +.\" AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL +.\" THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +.\" EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +.\" PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +.\" OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +.\" WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +.\" OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +.\" ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +.\" +.Dd November 20, 2000 +.Dt READPASSPHRASE 3 +.Os +.Sh NAME +.Nm readpassphrase +.Nd get a passphrase from the user +.Sh SYNOPSIS +.In readpassphrase.h +.Ft char * +.Fn readpassphrase "const char *prompt" "char *buf" "size_t bufsiz" "int flags" +.Sh DESCRIPTION +The +.Fn readpassphrase +function displays a prompt to, and reads in a passphrase from, +.Pa /dev/tty . +If this file is inaccessible +and the +.Dv RPP_REQUIRE_TTY +flag is not set, +.Fn readpassphrase +displays the prompt on the standard error output and reads from the standard +input. +In this case it is generally not possible to turn off echo. +.Pp +Up to +.Fa bufsiz +- 1 characters (one is for the NUL) are read into the provided buffer +.Fa buf . +Any additional +characters and the terminating newline (or return) character are discarded. +.Pp +.Fn readpassphrase +takes the following optional +.Fa flags : +.Pp +.Bd -literal -offset indent -compact +RPP_ECHO_OFF turn off echo (default behavior) +RPP_ECHO_ON leave echo on +RPP_REQUIRE_TTY fail if there is no tty +RPP_FORCELOWER force input to lower case +RPP_FORCEUPPER force input to upper case +RPP_SEVENBIT strip the high bit from input +.Ed +.Pp +The calling process should zero the passphrase as soon as possible to +avoid leaving the cleartext passphrase visible in the process's address +space. +.Sh RETURN VALUES +On success, +.Fn readpassphrase +returns a pointer to the null-terminated passphrase. +If the +.Dv RPP_REQUIRE_TTY +flag is set and +.Pa /dev/tty +is inaccessible, +.Fn readpassphrase +returns a null pointer. +.Sh FILES +.Bl -tag -width /dev/tty -compact +.It Pa /dev/tty +.El +.Sh EXAMPLES +The following code fragment will read a passphrase from +.Pa /dev/tty +into the buffer +.Fa passbuf . +.Bd -literal -offset indent +char passbuf[1024]; + +\&... + +if (readpassphrase("Response: ", passbuf, sizeof(passbuf), + RPP_REQUIRE_TTY) == NULL) + errx(1, "unable to read passphrase"); + +if (compare(transform(passbuf), epass) != 0) + errx(1, "bad passphrase"); + +\&... + +memset(passbuf, 0, sizeof(passbuf)); +.Ed +.Sh SEE ALSO +.Xr getpass 3 +.Sh HISTORY +The +.Fn readpassphrase +function first appeared in +.Ox 2.9 . diff --git a/crypto/dist/ssh/readpassphrase.c b/crypto/dist/ssh/readpassphrase.c new file mode 100644 index 000000000000..13a6d8a05ed4 --- /dev/null +++ b/crypto/dist/ssh/readpassphrase.c @@ -0,0 +1,133 @@ +/* $NetBSD: readpassphrase.c,v 1.6 2005/04/23 16:55:03 christos Exp $ */ +/* + * Copyright (c) 2000 Todd C. Miller + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL + * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#if defined(LIBC_SCCS) && !defined(lint) +static const char rcsid[] = "$OpenBSD: readpassphrase.c,v 1.7 2001/08/07 19:34:11 millert Exp $"; +#endif /* LIBC_SCCS and not lint */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +char * +readpassphrase(prompt, buf, bufsiz, flags) + const char *prompt; + char *buf; + size_t bufsiz; + int flags; +{ + struct termios term, oterm; + char ch, *p, *end; + int input, output; + sigset_t oset, nset; + + /* I suppose we could alloc on demand in this case (XXX). */ + if (bufsiz == 0) { + errno = EINVAL; + return(NULL); + } + + /* + * Read and write to /dev/tty if available. If not, read from + * stdin and write to stderr unless a tty is required. + */ + if ((input = output = open(_PATH_TTY, O_RDWR)) == -1) { + if (flags & RPP_REQUIRE_TTY) { + errno = ENOTTY; + return(NULL); + } + input = STDIN_FILENO; + output = STDERR_FILENO; + } + + /* + * We block SIGINT and SIGTSTP so the terminal is not left + * in an inconsistent state (ie: no echo). It would probably + * be better to simply catch these though. + */ + sigemptyset(&nset); + sigaddset(&nset, SIGINT); + sigaddset(&nset, SIGTSTP); + (void)sigprocmask(SIG_BLOCK, &nset, &oset); + + /* Turn off echo if possible. */ + if (tcgetattr(input, &oterm) == 0) { + memcpy(&term, &oterm, sizeof(term)); + if (!(flags & RPP_ECHO_ON) && (term.c_lflag & ECHO)) + term.c_lflag &= ~ECHO; + if (term.c_cc[VSTATUS] != _POSIX_VDISABLE) + term.c_cc[VSTATUS] = _POSIX_VDISABLE; + (void)tcsetattr(input, TCSAFLUSH|TCSASOFT, &term); + } else { + memset(&term, 0, sizeof(term)); + memset(&oterm, 0, sizeof(oterm)); + } + + (void)write(output, prompt, strlen(prompt)); + end = buf + bufsiz - 1; + for (p = buf; read(input, &ch, 1) == 1 && ch != '\n' && ch != '\r';) { + if (p < end) { + if ((flags & RPP_SEVENBIT)) + ch &= 0x7f; + if (isalpha((unsigned char)ch)) { + if ((flags & RPP_FORCELOWER)) + ch = tolower((unsigned char)ch); + if ((flags & RPP_FORCEUPPER)) + ch = toupper((unsigned char)ch); + } + *p++ = ch; + } + } + *p = '\0'; + if (!(term.c_lflag & ECHO)) + (void)write(output, "\n", 1); + + /* Restore old terminal settings and signal mask. */ + if (memcmp(&term, &oterm, sizeof(term)) != 0) + (void)tcsetattr(input, TCSAFLUSH|TCSASOFT, &oterm); + (void)sigprocmask(SIG_SETMASK, &oset, NULL); + if (input != STDIN_FILENO) + (void)close(input); + return(buf); +} + +char * +getpass(prompt) + const char *prompt; +{ + static char buf[_PASSWORD_LEN + 1]; + + return(readpassphrase(prompt, buf, sizeof(buf), RPP_ECHO_OFF)); +} diff --git a/crypto/dist/ssh/readpassphrase.h b/crypto/dist/ssh/readpassphrase.h new file mode 100644 index 000000000000..3b4216f9625f --- /dev/null +++ b/crypto/dist/ssh/readpassphrase.h @@ -0,0 +1,47 @@ +/* $NetBSD: readpassphrase.h,v 1.5 2005/04/23 16:55:03 christos Exp $ */ +/* $OpenBSD: readpassphrase.h,v 1.1 2000/11/21 00:48:38 millert Exp $ */ + +/* + * Copyright (c) 2000 Todd C. Miller + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL + * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _READPASSPHRASE_H_ +#define _READPASSPHRASE_H_ + +#define RPP_ECHO_OFF 0x00 /* Turn off echo (default). */ +#define RPP_ECHO_ON 0x01 /* Leave echo on. */ +#define RPP_REQUIRE_TTY 0x02 /* Fail if there is no tty. */ +#define RPP_FORCELOWER 0x04 /* Force input to lower case. */ +#define RPP_FORCEUPPER 0x08 /* Force input to upper case. */ +#define RPP_SEVENBIT 0x10 /* Strip the high bit from input. */ + +#include + +__BEGIN_DECLS +char * readpassphrase __P((const char *, char *, size_t, int)); +__END_DECLS + +#endif /* !_READPASSPHRASE_H_ */