Path: blob/main/crypto/krb5/src/appl/user_user/client.c
34890 views
/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */1/* appl/user_user/client.c - Other end of user-user client/server pair */2/*3* Copyright 1991 by the Massachusetts Institute of Technology.4* All Rights Reserved.5*6* Export of this software from the United States of America may7* require a specific license from the United States Government.8* It is the responsibility of any person or organization contemplating9* export to obtain such a license before exporting.10*11* WITHIN THAT CONSTRAINT, permission to use, copy, modify, and12* distribute this software and its documentation for any purpose and13* without fee is hereby granted, provided that the above copyright14* notice appear in all copies and that both that copyright notice and15* this permission notice appear in supporting documentation, and that16* the name of M.I.T. not be used in advertising or publicity pertaining17* to distribution of the software without specific, written prior18* permission. Furthermore if you modify this software you must label19* your software as modified software and not distribute it in such a20* fashion that it might be confused with the original M.I.T. software.21* M.I.T. makes no representations about the suitability of22* this software for any purpose. It is provided "as is" without express23* or implied warranty.24*/2526#include "k5-int.h"27#include "com_err.h"2829#include <sys/types.h>30#include <sys/socket.h>31#include <netinet/in.h>32#include <arpa/inet.h>33#include <netdb.h>3435int main (int argc, char *argv[])36{37int s;38int retval, i;39char *hname; /* full name of server */40char **srealms; /* realm(s) of server */41char *princ; /* principal in credentials cache */42struct servent *serv;43struct hostent *host;44struct sockaddr_in serv_net_addr, cli_net_addr;45krb5_ccache cc;46krb5_creds creds, *new_creds;47krb5_data reply, msg, princ_data;48krb5_auth_context auth_context = NULL;49krb5_ticket * ticket = NULL;50krb5_context context;51unsigned short port;5253if (argc < 2 || argc > 4) {54fputs ("usage: uu-client <hostname> [message [port]]\n", stderr);55exit(1);56}5758retval = krb5_init_context(&context);59if (retval) {60com_err(argv[0], retval, "while initializing krb5");61exit(1);62}6364if (argc == 4) {65port = htons(atoi(argv[3]));66}67else if ((serv = getservbyname ("uu-sample", "tcp")) == NULL)68{69fputs ("uu-client: unknown service \"uu-sample/tcp\"\n", stderr);70exit(2);71} else {72port = serv->s_port;73}7475if ((host = gethostbyname (argv[1])) == NULL) {76fprintf (stderr, "uu-client: can't get address of host \"%s\".\n",77argv[1]);78exit(3);79}8081if (host->h_addrtype != AF_INET) {82fprintf (stderr, "uu-client: bad address type %d for \"%s\".\n",83host->h_addrtype, argv[1]);84exit(3);85}8687hname = strdup (host->h_name);8889#ifndef USE_STDOUT90if ((s = socket(AF_INET, SOCK_STREAM, 0)) < 0) {91com_err ("uu-client", errno, "creating socket");92exit(4);93} else {94cli_net_addr.sin_family = AF_INET;95cli_net_addr.sin_port = 0;96cli_net_addr.sin_addr.s_addr = 0;97if (bind (s, (struct sockaddr *)&cli_net_addr,98sizeof (cli_net_addr)) < 0) {99com_err ("uu-client", errno, "binding socket");100exit(4);101}102}103104serv_net_addr.sin_family = AF_INET;105serv_net_addr.sin_port = port;106107i = 0;108while (1) {109if (host->h_addr_list[i] == 0) {110fprintf (stderr, "uu-client: unable to connect to \"%s\"\n", hname);111exit(5);112}113114memcpy (&serv_net_addr.sin_addr, host->h_addr_list[i++],115sizeof(serv_net_addr.sin_addr));116117if (connect(s, (struct sockaddr *)&serv_net_addr,118sizeof (serv_net_addr)) == 0)119break;120com_err ("uu-client", errno, "connecting to \"%s\" (%s).",121hname, inet_ntoa(serv_net_addr.sin_addr));122}123#else124s = 1;125#endif126127retval = krb5_cc_default(context, &cc);128if (retval) {129com_err("uu-client", retval, "getting credentials cache");130exit(6);131}132133memset (&creds, 0, sizeof(creds));134135retval = krb5_cc_get_principal(context, cc, &creds.client);136if (retval) {137com_err("uu-client", retval, "getting principal name");138exit(6);139}140141retval = krb5_unparse_name(context, creds.client, &princ);142if (retval) {143com_err("uu-client", retval, "printing principal name");144exit(7);145}146else147fprintf(stderr, "uu-client: client principal is \"%s\".\n", princ);148149retval = krb5_get_host_realm(context, hname, &srealms);150if (retval) {151com_err("uu-client", retval, "getting realms for \"%s\"", hname);152exit(7);153}154155retval =156krb5_build_principal_ext(context, &creds.server,157krb5_princ_realm(context,158creds.client)->length,159krb5_princ_realm(context,160creds.client)->data,1616, "krbtgt",162krb5_princ_realm(context,163creds.client)->length,164krb5_princ_realm(context,165creds.client)->data,1660);167if (retval) {168com_err("uu-client", retval, "setting up tgt server name");169exit(7);170}171172/* Get TGT from credentials cache */173retval = krb5_get_credentials(context, KRB5_GC_CACHED, cc,174&creds, &new_creds);175if (retval) {176com_err("uu-client", retval, "getting TGT");177exit(6);178}179180i = strlen(princ) + 1;181182fprintf(stderr, "uu-client: sending %d bytes\n",183new_creds->ticket.length + i);184princ_data.data = princ;185princ_data.length = i; /* include null terminator for186server's convenience */187retval = krb5_write_message(context, (krb5_pointer) &s, &princ_data);188if (retval) {189com_err("uu-client", retval, "sending principal name to server");190exit(8);191}192193free(princ);194195retval = krb5_write_message(context, (krb5_pointer) &s,196&new_creds->ticket);197if (retval) {198com_err("uu-client", retval, "sending ticket to server");199exit(8);200}201202retval = krb5_read_message(context, (krb5_pointer) &s, &reply);203if (retval) {204com_err("uu-client", retval, "reading reply from server");205exit(9);206}207208retval = krb5_auth_con_init(context, &auth_context);209if (retval) {210com_err("uu-client", retval, "initializing the auth_context");211exit(9);212}213214retval =215krb5_auth_con_genaddrs(context, auth_context, s,216KRB5_AUTH_CONTEXT_GENERATE_LOCAL_FULL_ADDR |217KRB5_AUTH_CONTEXT_GENERATE_REMOTE_FULL_ADDR);218if (retval) {219com_err("uu-client", retval, "generating addrs for auth_context");220exit(9);221}222223retval = krb5_auth_con_setflags(context, auth_context,224KRB5_AUTH_CONTEXT_DO_SEQUENCE);225if (retval) {226com_err("uu-client", retval, "initializing the auth_context flags");227exit(9);228}229230retval = krb5_auth_con_setuseruserkey(context, auth_context,231&new_creds->keyblock);232if (retval) {233com_err("uu-client", retval, "setting useruserkey for authcontext");234exit(9);235}236237/* read the ap_req to get the session key */238retval = krb5_rd_req(context, &auth_context, &reply, creds.client, NULL,239NULL, &ticket);240krb5_free_data_contents(context, &reply);241if (retval) {242com_err("uu-client", retval, "reading AP_REQ from server");243exit(9);244}245246retval = krb5_unparse_name(context, ticket->enc_part2->client, &princ);247if (retval)248com_err("uu-client", retval, "while unparsing client name");249else {250printf("server is named \"%s\"\n", princ);251free(princ);252}253254retval = krb5_read_message(context, (krb5_pointer) &s, &reply);255if (retval) {256com_err("uu-client", retval, "reading reply from server");257exit(9);258}259260retval = krb5_rd_safe(context, auth_context, &reply, &msg, NULL);261if (retval) {262com_err("uu-client", retval, "decoding reply from server");263exit(10);264}265266printf ("uu-client: server says \"%s\".\n", msg.data);267268#ifndef USE_STDOUT269close(s);270#endif271krb5_free_ticket(context, ticket);272krb5_free_host_realm(context, srealms);273free(hname);274krb5_free_cred_contents(context, &creds);275krb5_free_creds(context, new_creds);276krb5_free_data_contents(context, &msg);277krb5_free_data_contents(context, &reply);278krb5_cc_close(context, cc);279krb5_auth_con_free(context, auth_context);280krb5_free_context(context);281return 0;282}283284285