/** * shishi_authenticator_to_file: * @handle: shishi handle as allocated by shishi_init(). * @authenticator: Authenticator to save. * @filetype: input variable specifying type of file to be written, * see Shishi_filetype. * @filename: input variable with filename to write to. * * Write Authenticator to file in specified TYPE. The file will be * truncated if it exists. * * Return value: Returns SHISHI_OK iff successful. **/ int shishi_authenticator_to_file (Shishi * handle, Shishi_asn1 authenticator, int filetype, const char *filename) { FILE *fh; int res; if (VERBOSE (handle)) printf (_("Writing Authenticator to %s...\n"), filename); fh = fopen (filename, "w"); if (fh == NULL) return SHISHI_FOPEN_ERROR; if (VERBOSE (handle)) printf (_("Writing Authenticator in %s format...\n"), filetype == SHISHI_FILETYPE_TEXT ? "TEXT" : "DER"); if (filetype == SHISHI_FILETYPE_TEXT) res = shishi_authenticator_print (handle, fh, authenticator); else res = shishi_authenticator_save (handle, fh, authenticator); if (res != SHISHI_OK) return res; res = fclose (fh); if (res != 0) return SHISHI_IO_ERROR; if (VERBOSE (handle)) printf (_("Writing Authenticator to %s...done\n"), filename); return SHISHI_OK; }
/* shishi authentication */ int auth (Shishi * h, int verbose, const char *cname, const char *sname, int sock, char *cmd, char *port, Shishi_key ** enckey, Shishi_key * deckey) { Shishi_ap *ap; Shishi_tkt *tkt; Shishi_tkts_hint hint; int rc; char *out; int outlen; int krb5len, msglen; char auth; /* KERBEROS 5 SENDAUTH MESSAGE */ char krb5sendauth[] = "KRB5_SENDAUTH_V1.0"; /* PROTOCOL VERSION */ char krb5sendclient[] = "KCMDV0.2"; /* to store error msg sent by server */ char errormsg[101]; char cksumdata[101]; /* size of KRB5 auth message */ krb5len = strlen (krb5sendauth) + 1; msglen = htonl (krb5len); safewrite (sock, &msglen, sizeof (int)); /* KRB5 authentication message */ safewrite (sock, krb5sendauth, krb5len); /* size of client message */ krb5len = strlen (krb5sendclient) + 1; msglen = htonl (krb5len); safewrite (sock, &msglen, sizeof (int)); /* KRB5 client message */ safewrite (sock, krb5sendclient, krb5len); /* get answer from server 0 = ok, 1 = error with message */ read (sock, &auth, 1); if (auth) { read (sock, errormsg, 100); errormsg[100] = '\0'; printf ("Error during server authentication : %s\n", errormsg); return 1; } if (verbose) { printf ("Client: %s\n", cname); printf ("Server: %s\n", sname); } /* Get a ticket for the server. */ memset (&hint, 0, sizeof (hint)); hint.client = (char *) cname; hint.server = (char *) sname; tkt = shishi_tkts_get (shishi_tkts_default (h), &hint); if (!tkt) { printf ("cannot find ticket for \"%s\"\n", sname); return 1; } if (verbose) shishi_tkt_pretty_print (tkt, stderr); /* Create Authentication context */ rc = shishi_ap_tktoptions (h, &ap, tkt, SHISHI_APOPTIONS_MUTUAL_REQUIRED); if (rc != SHISHI_OK) { printf ("cannot create authentication context\n"); return 1; } /* checksum = port: terminal name */ snprintf (cksumdata, 100, "%s:%s%s", port, cmd, cname); /* add checksum to authenticator */ shishi_ap_authenticator_cksumdata_set (ap, cksumdata, strlen (cksumdata)); /* To be compatible with MIT rlogind */ shishi_ap_authenticator_cksumtype_set (ap, SHISHI_RSA_MD5); /* create der encoded AP-REQ */ rc = shishi_ap_req_der (ap, &out, &outlen); if (rc != SHISHI_OK) { printf ("cannot build authentication request: %s\n", shishi_strerror (rc)); return 1; } if (verbose) shishi_authenticator_print (h, stderr, shishi_ap_authenticator (ap)); /* extract subkey if present from ap exchange for secure connection */ shishi_authenticator_get_subkey (h, shishi_ap_authenticator (ap), enckey); /* send size of AP-REQ to the server */ msglen = htonl (outlen); safewrite (sock, (char *) &msglen, sizeof (int)); /* send AP-REQ to the server */ safewrite (sock, out, outlen); /* read a respond from server - what ? */ read (sock, &auth, sizeof (int)); /* For mutual authentication, wait for server reply. */ if (shishi_apreq_mutual_required_p (h, shishi_ap_req (ap))) { if (verbose) printf ("Waiting for server to authenticate itself...\n"); /* read size of the AP-REP */ read (sock, (char *) &outlen, sizeof (int)); /* read AP-REP */ outlen = ntohl (outlen); outlen = read (sock, out, outlen); rc = shishi_ap_rep_verify_der (ap, out, outlen); if (rc == SHISHI_OK) { if (verbose) printf ("AP-REP verification OK...\n"); } else { if (rc == SHISHI_APREP_VERIFY_FAILED) printf ("AP-REP verification failed...\n"); else printf ("AP-REP verification error: %s\n", shishi_strerror (rc)); return 1; } /* The server is authenticated. */ if (verbose) printf ("Server authenticated.\n"); } /* We are now authenticated. */ if (verbose) printf ("User authenticated.\n"); return AUTH_OK; }
static Shishi_ap * auth (Shishi * h, int verbose, const char *cname, const char *sname) { Shishi_key *key; Shishi_ap *ap; Shishi_asn1 apreq; char *buf; size_t buflen; int rc; printf ("Client: %s\n", cname); printf ("Server: %s\n", sname); /* Get key for the server. */ key = shishi_hostkeys_for_server (h, sname); if (!key) { printf ("could not find key: %s\n", shishi_error (h)); return NULL; } if (verbose) shishi_key_print (h, stderr, key); /* Read Authentication request from client */ printf ("Waiting for client to authenticate itself...\n"); rc = shishi_apreq_parse (h, stdin, &apreq); if (rc != SHISHI_OK) { printf ("could not read AP-REQ: %s\n", shishi_strerror (rc)); return NULL; } /* Create Authentication context */ rc = shishi_ap (h, &ap); if (rc != SHISHI_OK) { printf ("Could not create AP: %s\n", shishi_strerror (rc)); return NULL; } /* Store request in context */ shishi_ap_req_set (ap, apreq); /* Process authentication request */ rc = shishi_ap_req_process (ap, key); if (rc != SHISHI_OK) { printf ("Could not process AP-REQ: %s\n", shishi_strerror (rc)); return NULL; } if (verbose) shishi_authenticator_print (h, stderr, shishi_ap_authenticator (ap)); rc = shishi_authenticator_client (h, shishi_ap_authenticator (ap), &buf, &buflen); printf ("Client name (from authenticator): %.*s\n", (int) buflen, buf); free (buf); rc = shishi_encticketpart_clientrealm (h, shishi_tkt_encticketpart (shishi_ap_tkt (ap)), &buf, &buflen); printf ("Client name (from encticketpart): %.*s\n", (int) buflen, buf); free (buf); rc = shishi_ticket_server (h, shishi_tkt_ticket (shishi_ap_tkt (ap)), &buf, &buflen); printf ("Server name (from ticket): %.*s\n", (int) buflen, buf); free (buf); /* User is authenticated. */ printf ("User authenticated.\n"); /* Authenticate ourself to client, if request */ if (shishi_apreq_mutual_required_p (h, apreq)) { Shishi_asn1 aprep; printf ("Mutual authentication required.\n"); rc = shishi_ap_rep_asn1 (ap, &aprep); if (rc != SHISHI_OK) { printf ("Error creating AP-REP: %s\n", shishi_strerror (rc)); return NULL; } if (verbose) shishi_encapreppart_print (h, stderr, shishi_ap_encapreppart (ap)); shishi_aprep_print (h, stdout, aprep); /* We are authenticated to client */ } return ap; }
static Shishi_ap * auth (Shishi * h, int verbose, const char *cname, const char *sname) { Shishi_ap *ap; Shishi_tkt *tkt; Shishi_tkts_hint hint; int rc; printf ("Client: %s\n", cname); printf ("Server: %s\n", sname); /* Get a ticket for the server. */ memset (&hint, 0, sizeof (hint)); hint.client = (char *) cname; hint.server = (char *) sname; tkt = shishi_tkts_get (shishi_tkts_default (h), &hint); if (!tkt) { printf ("cannot find ticket for \"%s\"\n", sname); return NULL; } if (verbose) shishi_tkt_pretty_print (tkt, stderr); /* Create Authentication context */ rc = shishi_ap_tktoptions (h, &ap, tkt, SHISHI_APOPTIONS_MUTUAL_REQUIRED); if (rc != SHISHI_OK) { printf ("cannot create authentication context\n"); return NULL; } /* Build Authentication request */ rc = shishi_ap_req_build (ap); if (rc != SHISHI_OK) { printf ("cannot build authentication request: %s\n", shishi_strerror (rc)); return NULL; } if (verbose) shishi_authenticator_print (h, stderr, shishi_ap_authenticator (ap)); /* Authentication ourself to server */ shishi_apreq_print (h, stdout, shishi_ap_req (ap)); /* Note: to get the binary blob to send, use: * * char *out; int outlen; * ... * rc = shishi_ap_req_der (ap, &out, &outlen); * ... * write(fd, out, outlen); */ /* For mutual authentication, wait for server reply. */ if (shishi_apreq_mutual_required_p (h, shishi_ap_req (ap))) { Shishi_asn1 aprep; printf ("Waiting for server to authenticate itself...\n"); rc = shishi_aprep_parse (h, stdin, &aprep); if (rc != SHISHI_OK) { printf ("Cannot parse AP-REP from server: %s\n", shishi_strerror (rc)); return NULL; } rc = shishi_ap_rep_verify_asn1 (ap, aprep); if (rc == SHISHI_OK) printf ("AP-REP verification OK...\n"); else { if (rc == SHISHI_APREP_VERIFY_FAILED) printf ("AP-REP verification failed...\n"); else printf ("AP-REP verification error: %s\n", shishi_strerror (rc)); return NULL; } /* The server is authenticated. */ printf ("Server authenticated.\n"); } /* We are now authenticated. */ printf ("User authenticated.\n"); return ap; }
void test (Shishi * handle) { Shishi_asn1 a; char *p, *buf, *buf2; int res; size_t n, m; int32_t t; uint32_t s; /* shishi_authenticator */ a = shishi_authenticator (handle); if (debug) printf ("shishi_authenticator () => `%p'.\n", a); if (a) success ("shishi_authenticator() OK\n"); else fail ("shishi_authenticator() failed\n"); if (debug) shishi_authenticator_print (handle, stdout, a); res = shishi_authenticator_remove_subkey (handle, a); if (res == SHISHI_OK) success ("shishi_authenticator_remove_subkey() OK\n"); else fail ("shishi_authenticator_remove_subkey() failed\n"); /* shishi_authenticator_seqnumber_get */ res = shishi_authenticator_seqnumber_get (handle, a, &s); if (res == SHISHI_OK) success ("shishi_authenticator_seqnumber_get() OK\n"); else fail ("shishi_authenticator_seqnumber_get() failed\n"); /* shishi_authenticator_seqnumber_set */ res = shishi_authenticator_seqnumber_set (handle, a, 42); if (res == SHISHI_OK) success ("shishi_authenticator_seqnumber_set() OK\n"); else fail ("shishi_authenticator_seqnumber_set() failed\n"); /* shishi_authenticator_seqnumber_get */ res = shishi_authenticator_seqnumber_get (handle, a, &s); if (res == SHISHI_OK && s == 42) success ("shishi_authenticator_seqnumber_get() OK\n"); else fail ("shishi_authenticator_seqnumber_get() failed\n"); /* shishi_authenticator_seqnumber_remove */ res = shishi_authenticator_seqnumber_remove (handle, a); if (res == SHISHI_OK) success ("shishi_authenticator_seqnumber_remove() OK\n"); else fail ("shishi_authenticator_seqnumber_remove() failed\n"); /* shishi_authenticator_set_crealm */ res = shishi_authenticator_set_crealm (handle, a, "foo"); if (res == SHISHI_OK) success ("shishi_authenticator_set_crealm() OK\n"); else fail ("shishi_authenticator_set_crealm() failed\n"); /* shishi_authenticator_client_set */ res = shishi_authenticator_client_set (handle, a, "foo/bar/baz"); if (res == SHISHI_OK) success ("shishi_authenticator_client_set() OK\n"); else fail ("shishi_authenticator_client_set() failed\n"); /* shishi_authenticator_client */ res = shishi_authenticator_client (handle, a, &buf, &n); if (debug) escapeprint (buf, n); if (res == SHISHI_OK && n == strlen ("foo/bar/baz") && memcmp (buf, "foo/bar/baz", n) == 0) success ("shishi_authenticator_client() OK\n"); else fail ("shishi_authenticator_client() failed\n"); if (res == SHISHI_OK) free (buf); /* shishi_authenticator_client_set */ res = shishi_authenticator_client_set (handle, a, "foo"); if (res == SHISHI_OK) success ("shishi_authenticator_client_set() OK\n"); else fail ("shishi_authenticator_client_set() failed\n"); /* shishi_authenticator_client */ res = shishi_authenticator_client (handle, a, &buf, &n); if (debug) escapeprint (buf, n); if (res == SHISHI_OK && n == strlen ("foo") && memcmp (buf, "foo", n) == 0) success ("shishi_authenticator_client() OK\n"); else fail ("shishi_authenticator_client() failed\n"); if (res == SHISHI_OK) free (buf); /* shishi_authenticator_set_crealm */ res = shishi_authenticator_set_crealm (handle, a, "bar"); if (res == SHISHI_OK) success ("shishi_authenticator_set_crealm() OK\n"); else fail ("shishi_authenticator_set_crealm() failed\n"); /* shishi_authenticator_clientrealm */ res = shishi_authenticator_clientrealm (handle, a, &buf, &n); if (debug) escapeprint (buf, n); if (res == SHISHI_OK && n == strlen ("foo@bar") && memcmp (buf, "foo@bar", n) == 0) success ("shishi_authenticator_clientrealm() OK\n"); else fail ("shishi_authenticator_clientrealm() failed\n"); if (res == SHISHI_OK) free (buf); /* shishi_authenticator_add_authorizationdata */ res = shishi_authenticator_add_authorizationdata (handle, a, 42, "baz", 3); if (res == SHISHI_OK) success ("shishi_authenticator_add_authorizationdata() OK\n"); else fail ("shishi_authenticator_add_authorizationdata() failed\n"); /* shishi_authenticator_authorizationdata */ res = shishi_authenticator_authorizationdata (handle, a, &t, &buf, &m, 1); if (debug) escapeprint (buf, m); if (res == SHISHI_OK && t == 42 && m == 3 && memcmp (buf, "baz", 3) == 0) success ("shishi_authenticator_authorizationdata() OK\n"); else fail ("shishi_authenticator_authorizationdata() failed\n"); if (res == SHISHI_OK) free (buf); /* shishi_authenticator_authorizationdata */ res = shishi_authenticator_authorizationdata (handle, a, &t, &buf, &m, 2); if (res == SHISHI_OK) free (buf); if (res == SHISHI_OUT_OF_RANGE) success ("shishi_authenticator_authorizationdata() OK\n"); else fail ("shishi_authenticator_authorizationdata() failed\n"); /* shishi_authenticator_remove_cksum */ res = shishi_authenticator_remove_cksum (handle, a); if (res == SHISHI_OK) success ("shishi_authenticator_remove_cksum() OK\n"); else fail ("shishi_authenticator_remove_cksum() failed\n"); /* shishi_asn1_to_der */ res = shishi_asn1_to_der (handle, a, &buf, &n); if (res == SHISHI_OK) success ("shishi_asn1_to_der() OK\n"); else n = 0, fail ("shishi_asn1_to_der() failed\n"); /* shishi_authenticator_to_file */ res = shishi_authenticator_to_file (handle, a, SHISHI_FILETYPE_TEXT, "authenticator.tmp"); if (res == SHISHI_OK) success ("shishi_authenticator_to_file() OK\n"); else fail ("shishi_authenticator_to_file() failed\n"); /* shishi_asn1_done */ shishi_asn1_done (handle, a); success ("shishi_asn1_done() OK\n"); a = NULL; /* shishi_authenticator_from_file */ res = shishi_authenticator_from_file (handle, &a, SHISHI_FILETYPE_TEXT, "authenticator.tmp"); if (res == SHISHI_OK) success ("shishi_authenticator_from_file() OK\n"); else fail ("shishi_authenticator_from_file() failed\n"); if (debug) { /* shishi_authenticator_print */ res = shishi_authenticator_print (handle, stdout, a); if (res == SHISHI_OK) success ("shishi_authenticator_print() OK\n"); else fail ("shishi_authenticator_print() failed\n"); } /* shishi_asn1_to_der */ res = shishi_asn1_to_der (handle, a, &buf2, &m); if (res == SHISHI_OK) success ("shishi_asn1_to_der() OK\n"); else n = 0, fail ("shishi_asn1_to_der() failed\n"); /* Compare DER encodings of authenticators */ if (n > 0 && m > 0 && n == m && memcmp (buf, buf2, n) == 0) success ("DER comparison OK\n"); else fail ("DER comparison failed\n"); free (buf); free (buf2); /* shishi_authenticator_cusec_set */ res = shishi_authenticator_cusec_set (handle, a, 4711); if (res == SHISHI_OK) success ("shishi_authenticator_cusec_set() OK\n"); else fail ("shishi_authenticator_cusec_set() failed\n"); /* shishi_authenticator_cusec_get */ res = shishi_authenticator_cusec_get (handle, a, &s); if (debug) printf ("shishi_authenticator_cusec_get () => `%d'.\n", t); if (res == SHISHI_OK && s == 4711) success ("shishi_authenticator_cusec_get() OK\n"); else fail ("shishi_authenticator_cusec_get() failed\n"); /* shishi_authenticator_ctime_set */ res = shishi_authenticator_ctime_set (handle, a, "19700101011831Z"); if (res == SHISHI_OK) success ("shishi_authenticator_ctime_set() OK\n"); else fail ("shishi_authenticator_ctime_set() failed\n"); /* shishi_authenticator_ctime */ res = shishi_authenticator_ctime (handle, a, &p); if (debug) escapeprint (p, strlen (p)); if (res == SHISHI_OK && memcmp (p, "19700101011831Z", 15) == 0) success ("shishi_authenticator_ctime() OK\n"); else fail ("shishi_authenticator_ctime() failed\n"); if (res == SHISHI_OK) free (p); /* shishi_asn1_to_der */ res = shishi_asn1_to_der (handle, a, &buf, &n); if (res == SHISHI_OK) success ("shishi_asn1_to_der() OK\n"); else n = 0, fail ("shishi_asn1_to_der() failed\n"); if (debug) { shishi_authenticator_print (handle, stdout, a); hexprint (buf, n); puts (""); hexprint (authenticator, sizeof (authenticator)); puts (""); } if (n == sizeof (authenticator) && n == AUTHENTICATOR_LEN && memcmp (authenticator, buf, n) == 0) success ("DER comparison OK\n"); else fail ("DER comparison failed\n"); free (buf); /* shishi_authenticator_clear_authorizationdata */ res = shishi_authenticator_clear_authorizationdata (handle, a); if (res == SHISHI_OK) success ("shishi_authenticator_clear_authorizationdata() OK\n"); else fail ("shishi_authenticator_clear_authorizationdata() failed\n"); /* shishi_asn1_to_der */ res = shishi_asn1_to_der (handle, a, &buf, &n); if (res == SHISHI_OK) success ("shishi_asn1_to_der() OK\n"); else n = 0, fail ("shishi_asn1_to_der() failed\n"); if (debug) { shishi_authenticator_print (handle, stdout, a); hexprint (buf, n); puts (""); hexprint (authenticator2, sizeof (authenticator2)); puts (""); } if (n == sizeof (authenticator2) && n == AUTHENTICATOR2_LEN && memcmp (authenticator2, buf, n) == 0) success ("DER comparison OK\n"); else fail ("DER comparison failed\n"); free (buf); /* unlink */ res = unlink ("authenticator.tmp"); if (res == 0) success ("unlink() OK\n"); else fail ("unlink() failed\n"); /* shishi_asn1_done */ shishi_asn1_done (handle, a); success ("shishi_asn1_done() OK\n"); }