- if (options.gss_use_session_ccache) {
- snprintf(ccname,sizeof(ccname),"/tmp/krb5cc_%d_XXXXXX",geteuid());
-
- if ((tmpfd = mkstemp(ccname))==-1) {
- log("mkstemp(): %.100s", strerror(errno));
- return GSS_S_FAILURE;
- }
- if (fchmod(tmpfd, S_IRUSR | S_IWUSR) == -1) {
- log("fchmod(): %.100s", strerror(errno));
- close(tmpfd);
- return GSS_S_FAILURE;
- }
- } else {
- snprintf(ccname,sizeof(ccname),"/tmp/krb5cc_%d",geteuid());
- tmpfd = open(ccname, O_TRUNC | O_CREAT, S_IRUSR | S_IWUSR);
- if (tmpfd == -1) {
- log("open(): %.100s", strerror(errno));
- return GSS_S_FAILURE;
- }
- }
-
- close(tmpfd);
- snprintf(name, sizeof(name), "FILE:%s",ccname);
-
- if ((problem = krb5_cc_resolve(krb_context, name, &ccache))) {
- log("krb5_cc_default(): %.100s",
- krb5_get_err_text(krb_context,problem));
- return GSS_S_FAILURE;
- }
-
- if ((problem = krb5_parse_name(krb_context, gssapi_client_name.value,
- &princ))) {
- log("krb5_parse_name(): %.100s",
- krb5_get_err_text(krb_context,problem));
- krb5_cc_destroy(krb_context,ccache);
+ /*
+ * Extract the OID, and check it. Here GSSAPI breaks with tradition
+ * and does use the OID type and length bytes. To confuse things
+ * there are two lengths - the first including these, and the
+ * second without.
+ */
+
+ oidl = GET_16BIT(tok+2); /* length including next two bytes */
+ oidl = oidl-2; /* turn it into the _real_ length of the variable OID */
+
+ /*
+ * Check the BER encoding for correct type and length, that the
+ * string is long enough and that the OID matches that in our context
+ */
+ if (tok[4] != 0x06 || tok[5] != oidl ||
+ ename->length < oidl+6 ||
+ !ssh_gssapi_check_oid(ctx,tok+6,oidl))