00001
00008
00009
00010
00011 #ifdef KERBEROS5
00012 #include <stdio.h>
00013 #include <errno.h>
00014 #include <unistd.h>
00015 #include <sys/socket.h>
00016 #include <signal.h>
00017 #include <time.h>
00018 #include <krb5.h>
00019 #include <com_err.h>
00020 #include "proxylib.h"
00021
00022 PROXY_KRB5_INFO proxy_krb5_info;
00023
00024 char gridsolve_version[] = "GRIDSOLVE V0.1";
00025
00036 int
00037 proxy_send_krb5_credentials (char *server_hostname, int comm)
00038 {
00039 krb5_context context;
00040 krb5_auth_context auth_context = 0;
00041 krb5_error_code retval;
00042 krb5_principal client, server;
00043 krb5_ccache cc;
00044
00045 retval = krb5_init_context (&context);
00046 if (retval) {
00047 fprintf(stderr, "krb5_init_context failed: %s\n", error_message(retval));
00048 return -1;
00049 }
00050
00051
00052
00053
00054
00055
00056 retval = krb5_sname_to_principal(context, server_hostname,
00057 "GridSolve",
00058 KRB5_NT_SRV_HST, &server);
00059 if (retval) {
00060 fprintf (stderr, "krb5_sname_to_principal failed: %s\n",
00061 error_message (retval));
00062 return -1;
00063 }
00064
00065 retval = krb5_cc_default (context, &cc);
00066
00067 if (retval) {
00068 fprintf (stderr, "krb5_cc_default failed: %s\n",
00069 error_message (retval));
00070 krb5_free_principal (context, server);
00071 krb5_cc_close (context, cc);
00072 return -1;
00073 }
00074
00075 retval = krb5_cc_get_principal (context, cc, &client);
00076
00077 if (retval) {
00078 fprintf (stderr, "krb5_cc_get_principal failed: %s\n",
00079 error_message (retval));
00080 krb5_free_principal (context, server);
00081 krb5_cc_close (context, cc);
00082 return -1;
00083 }
00084
00085 retval = krb5_sendauth (context, &auth_context,
00086 (krb5_context) &comm,
00087 gridsolve_version,
00088 client, server,
00089 AP_OPTS_MUTUAL_REQUIRED | AP_OPTS_USE_SUBKEY,
00090 NULL, NULL, cc, 0, 0, NULL);
00091
00092 if (retval) {
00093 fprintf (stderr, "krb5_sendauth failed: %s\n",
00094 error_message (retval));
00095 krb5_free_principal (context, client);
00096 krb5_free_principal (context, server);
00097 krb5_cc_close (context, cc);
00098 return -1;
00099 }
00100
00101 return 0;
00102 }
00103
00112 int
00113 proxy_check_principal_name(char *name)
00114 {
00115 FILE *fp;
00116 char buf[1024];
00117
00118 if ((fp = fopen (proxy_krb5_info.users_file, "r")) == NULL) {
00119 fprintf (stderr, "cannot open %s: %s\n", proxy_krb5_info.users_file, strerror (errno));
00120 return -1;
00121 }
00122 while (fgets (buf, sizeof (buf), fp)) {
00123 char *ptr;
00124
00125
00126 if ( (ptr = strchr (buf, '#')) )
00127 *ptr = '\0';
00128
00129
00130 ptr = buf + strlen (buf);
00131 while (ptr > buf && (ptr[-1] == ' ' || ptr[-1] == '\t' ||
00132 ptr[-1] == '\n' || ptr[-1] == '\r'))
00133 *--ptr = '\0';
00134
00135
00136 for (ptr = buf; *ptr == ' ' || *ptr == '\t'; ++ptr);
00137
00138
00139 if (*ptr == '\0')
00140 continue;
00141
00142
00143 if (strcasecmp (ptr, name) == 0){
00144 return 1;
00145 }
00146 }
00147 fclose (fp);
00148 return -1;
00149 }
00150
00159 int
00160 proxy_recv_krb5_credentials(int comm)
00161 {
00162 krb5_error_code retval;
00163 krb5_auth_context auth_context = NULL;
00164 krb5_ticket *ticket;
00165 char *name;
00166
00167 fprintf(stderr, "Initializing Kerberos ... "); fflush(stderr);
00168 if(proxy_krb5_init() != 0){
00169 return -1;
00170 }
00171 fprintf(stderr, "success\n"); fflush(stderr);
00172
00173 fprintf(stderr, "Initializing Authentication Context ... "); fflush(stderr);
00174 retval = krb5_auth_con_init(proxy_krb5_info.context, &auth_context);
00175 if(retval){
00176 fprintf(stderr, "krb5_auth_con_init() failed: %s\n", error_message(retval));
00177 return -1;
00178 }
00179 fprintf(stderr, "success\n"); fflush(stderr);
00180
00181 fprintf(stderr, "Receiving authentication info from client ... "); fflush(stderr);
00182 retval = krb5_recvauth (proxy_krb5_info.context, &auth_context,
00183 (krb5_pointer) &comm, gridsolve_version,
00184 proxy_krb5_info.server, 0, proxy_krb5_info.keytab, &ticket);
00185 if (retval) {
00186 fprintf (stderr, "Authentication failed: %s\n",
00187 error_message(retval)); fflush(stderr);
00188 return -1;
00189 }
00190 fprintf(stderr, "success\n"); fflush(stderr);
00191
00192 krb5_unparse_name (proxy_krb5_info.context, ticket->enc_part2->client, &name);
00193 krb5_free_ticket (proxy_krb5_info.context, ticket);
00194
00195
00196
00197
00198
00199 fprintf(stderr, "Authenticated, checking if %s is authorized ... ", name); fflush(stderr);
00200 if (proxy_check_principal_name (name) < 0) {
00201 fprintf (stderr, "permission denied.\n"); fflush(stderr);
00202 return -1;
00203 }
00204 else{
00205 fprintf (stderr, "yes\n");
00206 fflush(stderr);
00207 }
00208
00209 free (name);
00210
00211 fprintf(stderr, "Freeing authentication context ... "); fflush(stderr);
00212 retval = krb5_auth_con_free(proxy_krb5_info.context, auth_context);
00213 if(retval){
00214 fprintf(stderr, "krb5_auth_con_free() failed: %s\n", error_message(retval));
00215 return -1;
00216 }
00217 fprintf(stderr, "success\n"); fflush(stderr);
00218
00219 return 0;
00220 }
00221
00232 int
00233 proxy_krb5_init()
00234 {
00235 krb5_error_code retval;
00236 char * keytab_filename;
00237 retval = krb5_init_context (&(proxy_krb5_info.context));
00238
00239 if (retval)
00240 {
00241 fprintf (stderr,
00242 "krb5_init_context failed: %s\n", error_message(retval));
00243 return -1;
00244 }
00245
00246 proxy_krb5_info.keytab = NULL;
00247 keytab_filename = getenv ("GRIDSOLVE_KEYTAB");
00248
00249 if (keytab_filename == NULL)
00250 {
00251 fprintf (stderr, "Environment variable GRIDSOLVE_KEYTAB not defined\n");
00252 return -1;
00253 }
00254
00255 retval = krb5_kt_resolve (proxy_krb5_info.context, keytab_filename, &(proxy_krb5_info.keytab));
00256 if(retval){
00257 fprintf (stderr, "krb5_kt_resolve() failed: %s\n", error_message(retval));
00258 return -1;
00259 }
00260
00261 proxy_krb5_info.users_file = getenv("GRIDSOLVE_USERS");
00262 if (proxy_krb5_info.users_file == NULL)
00263 {
00264 fprintf (stderr, "Environment variable GRIDSOLVE_USERS not defined\n");
00265 return -1;
00266 }
00267
00268 retval = krb5_sname_to_principal (proxy_krb5_info.context, NULL, "GridSolve",
00269 KRB5_NT_SRV_HST, &(proxy_krb5_info.server));
00270
00271 if (retval)
00272 {
00273 fprintf (stderr, "krb5_sname_to_principal() failed: %s\n",
00274 error_message (retval));
00275 return -1;
00276 }
00277
00278 return 0;
00279 }
00280
00281 #endif