From 07d69decb8d1d6475cb2e2e47e54cdb47a963786 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Ji=C5=99=C3=AD=20=C5=A0kr=C3=A1bal?= Date: Fri, 11 Feb 2005 10:48:58 +0000 Subject: [PATCH] - aplied recent lb_gss fixes - second server example added - some minor changes --- org.glite.security.gsoap-plugin/Makefile | 10 +- .../examples/wscalc_srv_ex.c | 56 +++------ .../examples/wscalc_srv_ex2.c | 130 +++++++++++++++++++++ .../interface/glite_gsplugin.h | 1 + org.glite.security.gsoap-plugin/interface/lb_gss.h | 15 ++- .../src/glite_gsplugin.c | 28 ++--- org.glite.security.gsoap-plugin/src/lb_gss.c | 40 +++++-- 7 files changed, 209 insertions(+), 71 deletions(-) create mode 100644 org.glite.security.gsoap-plugin/examples/wscalc_srv_ex2.c diff --git a/org.glite.security.gsoap-plugin/Makefile b/org.glite.security.gsoap-plugin/Makefile index 99bedba..b4fb2c5 100644 --- a/org.glite.security.gsoap-plugin/Makefile +++ b/org.glite.security.gsoap-plugin/Makefile @@ -19,7 +19,7 @@ gsoap_prefix=/opt/gsoap -include Makefile.inc -include ../Makefile.inc -GSPLUGIN_DEBUG:= yes +GSPLUGIN_DEBUG:= version_info=-version-info `echo ${version} | cut -d. -f1,2 | tr . :` @@ -129,7 +129,7 @@ test_coverage: cd coverage && for i in ${OBJS}; do gcov -o .libs/ $$i ; done -examples: soap_gen wscalc_clt_ex wscalc_srv_ex +examples: soap_gen wscalc_clt_ex wscalc_srv_ex wscalc_srv_ex2 GSOAP_FPREFIX:= GSOAP_ @@ -138,9 +138,12 @@ ifeq ($(GSPLUGIN_DEBUG),yes) stdsoap2.o WSCALC_SRV_OBJS = wscalc_srv_ex.o ${GSOAP_FPREFIX}C.o ${GSOAP_FPREFIX}Server.o \ stdsoap2.o + WSCALC_SRV2_OBJS = wscalc_srv_ex2.o ${GSOAP_FPREFIX}C.o ${GSOAP_FPREFIX}Server.o \ + stdsoap2.o else WSCALC_CLT_OBJS = wscalc_clt_ex.o ${GSOAP_FPREFIX}C.o ${GSOAP_FPREFIX}Client.o WSCALC_SRV_OBJS = wscalc_srv_ex.o ${GSOAP_FPREFIX}C.o ${GSOAP_FPREFIX}Server.o + WSCALC_SRV2_OBJS = wscalc_srv_ex2.o ${GSOAP_FPREFIX}C.o ${GSOAP_FPREFIX}Server.o endif @@ -150,6 +153,9 @@ wscalc_clt_ex: ${WSCALC_CLT_OBJS} ${STATICLIB} wscalc_srv_ex: ${WSCALC_SRV_OBJS} ${STATICLIB} ${LINK} -o $@ ${STATICLIB} ${GSOAP_LIBS} ${EX_LIBS} ${WSCALC_SRV_OBJS} +wscalc_srv_ex2: ${WSCALC_SRV2_OBJS} ${STATICLIB} + ${LINK} -o $@ ${STATICLIB} ${GSOAP_LIBS} ${EX_LIBS} ${WSCALC_SRV2_OBJS} + ${GSOAP_FPREFIX}H.h ${GSOAP_FPREFIX}C.c ${GSOAP_FPREFIX}Server.c ${GSOAP_FPREFIX}Client.c ${GSOAP_FPREFIX}ServerLib.c ${GSOAP_FPREFIX}ClientLib.c soap_gen: calc.h.S ${gsoap_prefix}/bin/soapcpp2 -c -p ${GSOAP_FPREFIX} ${top_srcdir}/examples/calc.h.S diff --git a/org.glite.security.gsoap-plugin/examples/wscalc_srv_ex.c b/org.glite.security.gsoap-plugin/examples/wscalc_srv_ex.c index 764605c..96d58f4 100644 --- a/org.glite.security.gsoap-plugin/examples/wscalc_srv_ex.c +++ b/org.glite.security.gsoap-plugin/examples/wscalc_srv_ex.c @@ -10,7 +10,6 @@ static struct option long_options[] = { { "cert", required_argument, NULL, 'c' }, { "key", required_argument, NULL, 'k' }, - { "CAdir", required_argument, NULL, 'd' }, { NULL, 0, NULL, 0 } }; @@ -20,69 +19,54 @@ usage(const char *me) fprintf(stderr, "usage: %s [option]\n" "\t-c, --cred\t certificate file\n" - "\t-k, --key\t private key file\n" - "\t-d, --CAdir\t trusted certificates directory\n", me); + "\t-k, --key\t private key file\n", me); } int main(int argc, char **argv) { - struct soap soap; - edg_wll_GssStatus gss_code; - gss_cred_id_t cred = GSS_C_NO_CREDENTIAL; - char *name, *msg; - char *cert, *key, *cadir; - int m, s; /* master and slave sockets */ - int opt; + struct soap soap; + glite_gsplugin_Context ctx = NULL; + char *name; + char *cert, *key; + int opt; - cert = key = cadir = NULL; + cert = key = NULL; name = strrchr(argv[0],'/'); if ( name ) name++; else name = argv[0]; - while ((opt = getopt_long(argc, argv, "c:k:d:", long_options, NULL)) != EOF) { + while ((opt = getopt_long(argc, argv, "c:k:", long_options, NULL)) != EOF) { switch (opt) { case 'c': cert = optarg; break; case 'k': key = optarg; break; - case 'd': cadir = optarg; break; case '?': default : usage(name); exit(1); } } if ( cert || key ) { - char *subject = NULL; - - if ( edg_wll_gss_acquire_cred_gsi(cert, key, - &cred, &subject, &gss_code) ) { - edg_wll_gss_get_error(&gss_code, "Failed to read credential", &msg); - fprintf(stderr, "%s\n", msg); - free(msg); - exit(1); - } - if (subject) { - printf("server running with certificate: %s\n", subject); - free(subject); - } + if ( glite_gsplugin_init_context(&ctx) ) { perror("init context"); exit(1); } + ctx->cert_filename = strdup(cert? : key); + ctx->key_filename = strdup(key? : cert); } soap_init(&soap); - if ( soap_register_plugin(&soap, glite_gsplugin) ) { + if ( soap_register_plugin_arg(&soap, glite_gsplugin, ctx? : NULL) ) { fprintf(stderr, "Can't register plugin\n"); exit(1); } - if ( (m = soap_bind(&soap, NULL, 9999, 100)) < 0 ) { + if ( soap_bind(&soap, NULL, 9999, 100) < 0 ) { soap_print_fault(&soap, stderr); exit(1); } while ( 1 ) { printf("accepting connection\n"); - s = soap_accept(&soap); - if ( s < 0 ) { + if ( soap_accept(&soap) < 0 ) { fprintf(stderr, "soap_accept() failed!!!\n"); soap_print_fault(&soap, stderr); fprintf(stderr, "plugin err: %s", glite_gsplugin_errdesc(&soap)); @@ -95,14 +79,12 @@ main(int argc, char **argv) fprintf(stderr, "plugin err: %s", glite_gsplugin_errdesc(&soap)); } - /* clean up class instances - */ - soap_destroy(&soap); - /* clean up everything and close socket - */ - soap_end(&soap); + soap_destroy(&soap); /* clean up class instances */ + soap_end(&soap); /* clean up everything and close socket */ } - soap_done(&soap); // close master socket + soap_done(&soap); /* close master socket */ + + if ( ctx ) glite_gsplugin_free_context(ctx); return 0; } diff --git a/org.glite.security.gsoap-plugin/examples/wscalc_srv_ex2.c b/org.glite.security.gsoap-plugin/examples/wscalc_srv_ex2.c new file mode 100644 index 0000000..e32fc46 --- /dev/null +++ b/org.glite.security.gsoap-plugin/examples/wscalc_srv_ex2.c @@ -0,0 +1,130 @@ +#include +#include +#include +#include + +#include "GSOAP_H.h" +#include "wscalc.nsmap" + + +static struct option long_options[] = { + { "cert", required_argument, NULL, 'c' }, + { "key", required_argument, NULL, 'k' }, + { "port", required_argument, NULL, 'p' }, + { NULL, 0, NULL, 0 } +}; + +void +usage(const char *me) +{ + fprintf(stderr, + "usage: %s [option]\n" + "\t-p, --port\t listening port\n" + "\t-c, --cred\t certificate file\n" + "\t-k, --key\t private key file\n", me); +} + + +int +main(int argc, char **argv) +{ + struct soap soap; + edg_wll_GssStatus gss_code; + glite_gsplugin_Context ctx; + struct sockaddr_in a; + int alen; + char *name, *msg; + char *subject = NULL; + int opt, + port = 9999; + int sock; + + + name = strrchr(argv[0],'/'); + if ( name ) name++; else name = argv[0]; + + if ( glite_gsplugin_init_context(&ctx) ) { perror("init context"); exit(1); } + + while ((opt = getopt_long(argc, argv, "c:k:p:", long_options, NULL)) != EOF) { + switch (opt) { + case 'p': port = atoi(optarg); break; + case 'c': ctx->cert_filename = strdup(optarg); break; + case 'k': ctx->key_filename = strdup(optarg); break; + case '?': + default : usage(name); exit(1); + } + } + + if ( edg_wll_gss_acquire_cred_gsi(ctx->cert_filename, ctx->key_filename, &ctx->cred, &subject, &gss_code) ) { + edg_wll_gss_get_error(&gss_code, "Failed to read credential", &msg); + fprintf(stderr, "%s\n", msg); + free(msg); + exit(1); + } + if (subject) { + printf("server running with certificate: %s\n", subject); + free(subject); + } + + soap_init(&soap); + + if ( soap_register_plugin_arg(&soap, glite_gsplugin, ctx) ) { + fprintf(stderr, "Can't register plugin\n"); + exit(1); + } + + alen = sizeof(a); + if ( (sock = socket(PF_INET,SOCK_STREAM,0)) < 0 ) { perror("socket()"); exit(1); } + a.sin_family = AF_INET; + a.sin_port = htons(port); + a.sin_addr.s_addr = INADDR_ANY; + if ( bind(sock, (struct sockaddr *)&a, sizeof(a)) ) { perror("bind()"); exit(1); } + if ( listen(sock, 100) ) { perror("listen()"); exit(1); } + if ( !(ctx->connection = malloc(sizeof(*ctx->connection))) ) exit(1); + + bzero((char *) &a, alen); + + while ( 1 ) { + int conn; + + printf("accepting connection\n"); + if ( (conn = accept(sock, (struct sockaddr *) &a, &alen)) < 0 ) { + close(sock); + perror("accept"); + exit(1); + } + if ( edg_wll_gss_accept(ctx->cred,conn,&ctx->timeout,ctx->connection,&gss_code) ){ + edg_wll_gss_get_error(&gss_code, "Failed to read credential", &msg); + fprintf(stderr, "%s\n", msg); + free(msg); + exit(1); + } + + printf("serving connection\n"); + if ( soap_serve(&soap) ) { + soap_print_fault(&soap, stderr); + fprintf(stderr, "plugin err: %s", glite_gsplugin_errdesc(&soap)); + } + + soap_destroy(&soap); /* clean up class instances */ + soap_end(&soap); /* clean up everything and close socket */ + } + + soap_done(&soap); /* close master socket */ + + glite_gsplugin_free_context(ctx); + + return 0; +} + +int wscalc__add(struct soap *soap, double a, double b, double *result) +{ + *result = a + b; + return SOAP_OK; +} + +int wscalc__sub(struct soap *soap, double a, double b, double *result) +{ + *result = a - b; + return SOAP_OK; +} diff --git a/org.glite.security.gsoap-plugin/interface/glite_gsplugin.h b/org.glite.security.gsoap-plugin/interface/glite_gsplugin.h index 4184c38..4d33eee 100644 --- a/org.glite.security.gsoap-plugin/interface/glite_gsplugin.h +++ b/org.glite.security.gsoap-plugin/interface/glite_gsplugin.h @@ -25,6 +25,7 @@ struct _glite_gsplugin_ctx { typedef struct _glite_gsplugin_ctx *glite_gsplugin_Context; extern int glite_gsplugin_init_context(glite_gsplugin_Context *); +extern int glite_gsplugin_free_context(glite_gsplugin_Context); extern int glite_gsplugin(struct soap *, struct soap_plugin *, void *); extern char *glite_gsplugin_errdesc(struct soap *); diff --git a/org.glite.security.gsoap-plugin/interface/lb_gss.h b/org.glite.security.gsoap-plugin/interface/lb_gss.h index c0c8a71..3dd4903 100644 --- a/org.glite.security.gsoap-plugin/interface/lb_gss.h +++ b/org.glite.security.gsoap-plugin/interface/lb_gss.h @@ -1,6 +1,8 @@ #ifndef __EDG_WORKLOAD_LOGGING_COMMON_LB_GSS_H__ #define __EDG_WORKLOAD_LOGGING_COMMON_LB_GSS_H__ +#ident "$Header$" + #include #ifdef __cplusplus @@ -19,7 +21,7 @@ enum { typedef struct _edg_wll_GssConnection { gss_ctx_id_t context; int sock; - char buffer[BUFSIZ]; + char *buffer; size_t bufsize; } edg_wll_GssConnection; @@ -28,6 +30,8 @@ typedef struct _edg_wll_GssStatus { OM_uint32 minor_status; } edg_wll_GssStatus; +/* XXX Support anonymous connections. Are we able/required to support + * anonymous servers as well. */ int edg_wll_gss_acquire_cred_gsi(char *cert_file, @@ -99,10 +103,15 @@ edg_wll_gss_reject(int sock); int edg_wll_gss_oid_equal(const gss_OID a, - const gss_OID b); + const gss_OID b); + +/* +int +edg_wll_gss_get_name(gss_cred_id_t cred, char **name); +*/ #ifdef __cplusplus } #endif -#endif +#endif /* __EDG_WORKLOAD_LOGGING_COMMON_LB_GSS_H__ */ diff --git a/org.glite.security.gsoap-plugin/src/glite_gsplugin.c b/org.glite.security.gsoap-plugin/src/glite_gsplugin.c index 431584b..a3c607c 100644 --- a/org.glite.security.gsoap-plugin/src/glite_gsplugin.c +++ b/org.glite.security.gsoap-plugin/src/glite_gsplugin.c @@ -100,11 +100,12 @@ glite_gsplugin(struct soap *soap, struct soap_plugin *p, void *arg) p->fdelete = glite_gsplugin_delete; p->fcopy = glite_gsplugin_copy; - soap->fconnect = glite_gsplugin_connect; - soap->fclose = glite_gsplugin_close; - soap->faccept = glite_gsplugin_accept; - soap->fsend = glite_gsplugin_send; - soap->frecv = glite_gsplugin_recv; + soap->fconnect = glite_gsplugin_connect; + soap->fclose = glite_gsplugin_close; + soap->fclosesocket = glite_gsplugin_close; + soap->faccept = glite_gsplugin_accept; + soap->fsend = glite_gsplugin_send; + soap->frecv = glite_gsplugin_recv; return SOAP_OK; @@ -185,12 +186,6 @@ glite_gsplugin_connect( goto err; } - /* XXX: co s tim??? - * - soap->socket = 2; - */ - - return SOAP_OK; err: pdprintf(("GSLITE_GSPLUGIN: glite_gsplugin_connect() error!\n")); @@ -223,8 +218,7 @@ glite_gsplugin_close(struct soap *soap) ret = edg_wll_gss_close(ctx->connection, (ctx->timeout.tv_usec || ctx->timeout.tv_sec)? &ctx->timeout: NULL); } - free(ctx->connection); - ctx->connection = NULL; + ctx->connection->context = GSS_C_NO_CONTEXT; } return ret; @@ -261,12 +255,14 @@ glite_gsplugin_recv(struct soap *soap, char *buf, size_t bufsz) int len; + pdprintf(("GSLITE_GSPLUGIN: glite_gsplugin_recv()\n")); ctx = ((int_plugin_data_t *)soap_lookup_plugin(soap, plugin_id))->ctx; if ( ctx->error_msg ) { free(ctx->error_msg); ctx->error_msg = NULL; } if ( ctx->connection->context == GSS_C_NO_CONTEXT ) { soap->errnum = ENOTCONN; - /* XXX glite_gsplugin_send() returns SOAP_EOF on errors */ + /* XXX: glite_gsplugin_send() returns SOAP_EOF on errors + */ return 0; } @@ -300,7 +296,6 @@ glite_gsplugin_recv(struct soap *soap, char *buf, size_t bufsz) /* default: fallthrough */ } - pdprintf(("\nWS received:\n%s\n\n", buf)); return len; } @@ -314,7 +309,7 @@ glite_gsplugin_send(struct soap *soap, const char *buf, size_t bufsz) int ret; - pdprintf(("GSLITE_GSPLUGIN: glite_gsplugin_send():\n%s\n\n", buf)); + pdprintf(("GSLITE_GSPLUGIN: glite_gsplugin_send()\n")); ctx = ((int_plugin_data_t *)soap_lookup_plugin(soap, plugin_id))->ctx; /* XXX: check whether ctx is initialized * i.e. ctx->connection != NULL @@ -337,7 +332,6 @@ glite_gsplugin_send(struct soap *soap, const char *buf, size_t bufsz) switch ( ret ) { case EDG_WLL_GSS_OK: - pdprintf(("\nWS sent:\n%s\n\n", buf)); break; case EDG_WLL_GSS_ERROR_TIMEOUT: diff --git a/org.glite.security.gsoap-plugin/src/lb_gss.c b/org.glite.security.gsoap-plugin/src/lb_gss.c index a9908a3..0142a83 100644 --- a/org.glite.security.gsoap-plugin/src/lb_gss.c +++ b/org.glite.security.gsoap-plugin/src/lb_gss.c @@ -1,4 +1,3 @@ -/* /cvs/jra1mw/org.glite.lb.common/src/lb_gss.c,v 1.3 2004/10/21 10:20:12 dkouril*/ #ident "$Header$" #include @@ -761,7 +760,7 @@ edg_wll_gss_write(edg_wll_GssConnection *connection, const void *buf, size_t buf input_token.value = (void*)buf; input_token.length = bufsize; - maj_stat = gss_wrap (&min_stat, connection->context, 0, GSS_C_QOP_DEFAULT, + maj_stat = gss_wrap (&min_stat, connection->context, 1, GSS_C_QOP_DEFAULT, &input_token, NULL, &output_token); if (GSS_ERROR(maj_stat)) { if (gss_code) { @@ -794,11 +793,14 @@ edg_wll_gss_read(edg_wll_GssConnection *connection, void *buf, size_t bufsize, len = (connection->bufsize < bufsize) ? connection->bufsize : bufsize; memcpy(buf, connection->buffer, len); - connection->bufsize -= len; - if (connection->bufsize > 0) { - for (i = 0; i < sizeof(connection->buffer) - len; i++) + if (connection->bufsize - len == 0) { + free(connection->buffer); + connection->buffer = NULL; + } else { + for (i = 0; i < connection->bufsize - len; i++) connection->buffer[i] = connection->buffer[i+len]; } + connection->bufsize -= len; return len; } @@ -812,6 +814,7 @@ edg_wll_gss_read(edg_wll_GssConnection *connection, void *buf, size_t bufsize, maj_stat = gss_unwrap(&min_stat, connection->context, &input_token, &output_token, NULL, NULL); + gss_release_buffer(&min_stat, &input_token); if (GSS_ERROR(maj_stat)) { /* XXX cleanup */ return EDG_WLL_GSS_ERROR_GSS; @@ -819,15 +822,24 @@ edg_wll_gss_read(edg_wll_GssConnection *connection, void *buf, size_t bufsize, } while (maj_stat == 0 && output_token.length == 0 && output_token.value == NULL); if (output_token.length > bufsize) { - if (output_token.length - bufsize > sizeof(connection->buffer)) - return EINVAL; connection->bufsize = output_token.length - bufsize; + connection->buffer = malloc(connection->bufsize); + if (connection->buffer == NULL) { + connection->bufsize = 0; + ret = EDG_WLL_GSS_ERROR_ERRNO; + goto end; + } memcpy(connection->buffer, output_token.value + bufsize, connection->bufsize); output_token.length = bufsize; } + memcpy(buf, output_token.value, output_token.length); + ret = output_token.length; - return output_token.length; +end: + gss_release_buffer(&min_stat, &output_token); + + return ret; } int @@ -841,14 +853,16 @@ edg_wll_gss_read_full(edg_wll_GssConnection *connection, void *buf, if (connection->bufsize > 0) { size_t len; - len = (connection->bufsize < bufsize) ? connection->bufsize : bufsize; memcpy(buf, connection->buffer, len); - connection->bufsize -= len; - if (connection->bufsize > 0) { - for (i = 0; i < sizeof(connection->buffer) - len; i++) + if (connection->bufsize - len == 0) { + free(connection->buffer); + connection->buffer = NULL; + } else { + for (i = 0; i < connection->bufsize - len; i++) connection->buffer[i] = connection->buffer[i+len]; } + connection->bufsize -= len; *total = len; } @@ -907,6 +921,8 @@ edg_wll_gss_close(edg_wll_GssConnection *con, struct timeval *timeout) if (con->sock >= 0) close(con->sock); } + if (con->buffer) + free(con->buffer); memset(con, 0, sizeof(*con)); con->context = GSS_C_NO_CONTEXT; con->sock = -1; -- 1.8.2.3