Path: blob/main/crypto/krb5/src/plugins/authdata/greet_client/greet.c
34909 views
/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */1/* plugins/authdata/greet_client/greet.c - Sample authorization data plugin */2/*3* Copyright 2009 by the Massachusetts Institute of Technology.4*5* Export of this software from the United States of America may6* require a specific license from the United States Government.7* It is the responsibility of any person or organization contemplating8* export to obtain such a license before exporting.9*10* WITHIN THAT CONSTRAINT, permission to use, copy, modify, and11* distribute this software and its documentation for any purpose and12* without fee is hereby granted, provided that the above copyright13* notice appear in all copies and that both that copyright notice and14* this permission notice appear in supporting documentation, and that15* the name of M.I.T. not be used in advertising or publicity pertaining16* to distribution of the software without specific, written prior17* permission. Furthermore if you modify this software you must label18* your software as modified software and not distribute it in such a19* fashion that it might be confused with the original M.I.T. software.20* M.I.T. makes no representations about the suitability of21* this software for any purpose. It is provided "as is" without express22* or implied warranty.23*/2425#include "k5-int.h"26#include <krb5/authdata_plugin.h>27#include <assert.h>2829struct greet_context {30krb5_data greeting;31krb5_boolean verified;32};3334static krb5_data greet_attr = {35KV5M_DATA, sizeof("urn:greet:greeting") - 1, "urn:greet:greeting" };3637static krb5_error_code38greet_init(krb5_context kcontext, void **plugin_context)39{40*plugin_context = 0;41return 0;42}4344static void45greet_flags(krb5_context kcontext,46void *plugin_context,47krb5_authdatatype ad_type,48krb5_flags *flags)49{50*flags = AD_USAGE_AP_REQ | AD_USAGE_KDC_ISSUED | AD_INFORMATIONAL;51}5253static void54greet_fini(krb5_context kcontext, void *plugin_context)55{56return;57}5859static krb5_error_code60greet_request_init(krb5_context kcontext,61krb5_authdata_context context,62void *plugin_context,63void **request_context)64{65struct greet_context *greet;6667greet = malloc(sizeof(*greet));68if (greet == NULL)69return ENOMEM;7071greet->greeting.data = NULL;72greet->greeting.length = 0;73greet->verified = FALSE;7475*request_context = greet;7677return 0;78}7980static krb5_error_code81greet_export_authdata(krb5_context kcontext,82krb5_authdata_context context,83void *plugin_context,84void *request_context,85krb5_flags usage,86krb5_authdata ***out_authdata)87{88struct greet_context *greet = (struct greet_context *)request_context;89krb5_authdata *data[2];90krb5_authdata datum;91krb5_error_code code;9293datum.ad_type = -42;94datum.length = greet->greeting.length;95datum.contents = (krb5_octet *)greet->greeting.data;9697data[0] = &datum;98data[1] = NULL;99100code = krb5_copy_authdata(kcontext, data, out_authdata);101102return code;103}104105static krb5_error_code106greet_import_authdata(krb5_context kcontext,107krb5_authdata_context context,108void *plugin_context,109void *request_context,110krb5_authdata **authdata,111krb5_boolean kdc_issued_flag,112krb5_const_principal issuer)113{114krb5_error_code code;115struct greet_context *greet = (struct greet_context *)request_context;116krb5_data data;117118krb5_free_data_contents(kcontext, &greet->greeting);119greet->verified = FALSE;120121assert(authdata[0] != NULL);122123data.length = authdata[0]->length;124data.data = (char *)authdata[0]->contents;125126code = krb5int_copy_data_contents_add0(kcontext, &data, &greet->greeting);127if (code == 0)128greet->verified = kdc_issued_flag;129130return code;131}132133static void134greet_request_fini(krb5_context kcontext,135krb5_authdata_context context,136void *plugin_context,137void *request_context)138{139struct greet_context *greet = (struct greet_context *)request_context;140141if (greet != NULL) {142krb5_free_data_contents(kcontext, &greet->greeting);143free(greet);144}145}146147static krb5_error_code148greet_get_attribute_types(krb5_context kcontext,149krb5_authdata_context context,150void *plugin_context,151void *request_context,152krb5_data **out_attrs)153{154krb5_error_code code;155struct greet_context *greet = (struct greet_context *)request_context;156157if (greet->greeting.length == 0)158return ENOENT;159160*out_attrs = calloc(2, sizeof(krb5_data));161if (*out_attrs == NULL)162return ENOMEM;163164code = krb5int_copy_data_contents_add0(kcontext,165&greet_attr,166&(*out_attrs)[0]);167if (code != 0) {168free(*out_attrs);169*out_attrs = NULL;170return code;171}172173return 0;174}175176static krb5_error_code177greet_get_attribute(krb5_context kcontext,178krb5_authdata_context context,179void *plugin_context,180void *request_context,181const krb5_data *attribute,182krb5_boolean *authenticated,183krb5_boolean *complete,184krb5_data *value,185krb5_data *display_value,186int *more)187{188struct greet_context *greet = (struct greet_context *)request_context;189krb5_error_code code;190191if (!data_eq(*attribute, greet_attr) || greet->greeting.length == 0)192return ENOENT;193194*authenticated = greet->verified;195*complete = TRUE;196*more = 0;197198code = krb5int_copy_data_contents_add0(kcontext, &greet->greeting, value);199if (code == 0) {200code = krb5int_copy_data_contents_add0(kcontext,201&greet->greeting,202display_value);203if (code != 0)204krb5_free_data_contents(kcontext, value);205}206207return code;208}209210static krb5_error_code211greet_set_attribute(krb5_context kcontext,212krb5_authdata_context context,213void *plugin_context,214void *request_context,215krb5_boolean complete,216const krb5_data *attribute,217const krb5_data *value)218{219struct greet_context *greet = (struct greet_context *)request_context;220krb5_data data;221krb5_error_code code;222223if (!data_eq(*attribute, greet_attr))224return ENOENT;225226if (greet->greeting.data != NULL)227return EEXIST;228229code = krb5int_copy_data_contents_add0(kcontext, value, &data);230if (code != 0)231return code;232233krb5_free_data_contents(kcontext, &greet->greeting);234greet->greeting = data;235greet->verified = FALSE;236237return 0;238}239240static krb5_error_code241greet_delete_attribute(krb5_context kcontext,242krb5_authdata_context context,243void *plugin_context,244void *request_context,245const krb5_data *attribute)246{247struct greet_context *greet = (struct greet_context *)request_context;248249krb5_free_data_contents(kcontext, &greet->greeting);250greet->verified = FALSE;251252return 0;253}254255static krb5_error_code256greet_size(krb5_context kcontext,257krb5_authdata_context context,258void *plugin_context,259void *request_context,260size_t *sizep)261{262struct greet_context *greet = (struct greet_context *)request_context;263264*sizep += sizeof(krb5_int32) +265greet->greeting.length +266sizeof(krb5_int32);267268return 0;269}270271static krb5_error_code272greet_externalize(krb5_context kcontext,273krb5_authdata_context context,274void *plugin_context,275void *request_context,276krb5_octet **buffer,277size_t *lenremain)278{279size_t required = 0;280struct greet_context *greet = (struct greet_context *)request_context;281282greet_size(kcontext, context, plugin_context,283request_context, &required);284285if (*lenremain < required)286return ENOMEM;287288/* Greeting Length | Greeting Contents | Verified */289krb5_ser_pack_int32(greet->greeting.length, buffer, lenremain);290krb5_ser_pack_bytes((krb5_octet *)greet->greeting.data,291(size_t)greet->greeting.length,292buffer, lenremain);293krb5_ser_pack_int32((krb5_int32)greet->verified, buffer, lenremain);294295return 0;296}297298static krb5_error_code299greet_internalize(krb5_context kcontext,300krb5_authdata_context context,301void *plugin_context,302void *request_context,303krb5_octet **buffer,304size_t *lenremain)305{306struct greet_context *greet = (struct greet_context *)request_context;307krb5_error_code code;308krb5_int32 length;309krb5_octet *contents = NULL;310krb5_int32 verified;311krb5_octet *bp;312size_t remain;313314bp = *buffer;315remain = *lenremain;316317/* Greeting Length */318code = krb5_ser_unpack_int32(&length, &bp, &remain);319if (code != 0)320return code;321322/* Greeting Contents */323if (length != 0) {324contents = malloc(length);325if (contents == NULL)326return ENOMEM;327328code = krb5_ser_unpack_bytes(contents, (size_t)length, &bp, &remain);329if (code != 0) {330free(contents);331return code;332}333}334335/* Verified */336code = krb5_ser_unpack_int32(&verified, &bp, &remain);337if (code != 0) {338free(contents);339return code;340}341342krb5_free_data_contents(kcontext, &greet->greeting);343greet->greeting.length = length;344greet->greeting.data = (char *)contents;345greet->verified = (verified != 0);346347*buffer = bp;348*lenremain = remain;349350return 0;351}352353static krb5_authdatatype greet_ad_types[] = { -42, 0 };354355krb5plugin_authdata_client_ftable_v0 authdata_client_0 = {356"greet",357greet_ad_types,358greet_init,359greet_fini,360greet_flags,361greet_request_init,362greet_request_fini,363greet_get_attribute_types,364greet_get_attribute,365greet_set_attribute,366greet_delete_attribute,367greet_export_authdata,368greet_import_authdata,369NULL,370NULL,371NULL,372greet_size,373greet_externalize,374greet_internalize,375NULL376};377378379