comparison lib-src/pop.c @ 19018:f1f7c254aa77

Support auto-configuration of both Kerberos V4 and Kerberos V5 for movemail, including detection of V4 and V5 header files and libraries. Include <string.h> when STDC_HEADERS is defined, to get declarations of string functions. [KERBEROS5] (socket_connection): Support the current MIT Kerberos V5 API rather than the old one. [KERBEROS] (socket_connection): Change a constant name from SOCKET_ERROR to POP_SOCKET_ERROR to avoid a namespace conflict with a constant in a header file.
author Richard M. Stallman <rms@gnu.org>
date Mon, 28 Jul 1997 05:52:35 +0000
parents 975d093d45fb
children 83050d7e3f64
comparison
equal deleted inserted replaced
19017:8666fad79dd0 19018:f1f7c254aa77
1 /* pop.c: client routines for talking to a POP3-protocol post-office server 1 /* pop.c: client routines for talking to a POP3-protocol post-office server
2 Copyright (c) 1991, 1993, 1996 Free Software Foundation, Inc. 2 Copyright (c) 1991, 1993, 1996, 1997 Free Software Foundation, Inc.
3 Written by Jonathan Kamens, jik@security.ov.com. 3 Written by Jonathan Kamens, jik@security.ov.com.
4 4
5 This file is part of GNU Emacs. 5 This file is part of GNU Emacs.
6 6
7 GNU Emacs is free software; you can redistribute it and/or modify 7 GNU Emacs is free software; you can redistribute it and/or modify
70 70
71 #include <pwd.h> 71 #include <pwd.h>
72 #include <netdb.h> 72 #include <netdb.h>
73 #include <errno.h> 73 #include <errno.h>
74 #include <stdio.h> 74 #include <stdio.h>
75 #ifdef STDC_HEADERS
76 #include <string.h>
77 #endif
75 78
76 #ifdef KERBEROS 79 #ifdef KERBEROS
77 #ifndef KRB5 80 # ifdef HAVE_KRB5_H
78 #ifndef SOLARIS2 81 # include <krb5.h>
79 #include <des.h> 82 # endif
80 #include <krb.h> 83 # ifdef HAVE_DES_H
81 #else /* not SOLARIS2 */ 84 # include <des.h>
82 #include <kerberos/des.h> 85 # else
83 #include <kerberos/krb.h> 86 # ifdef HAVE_KERBEROSIV_DES_H
84 #endif /* not SOLARIS2 */ 87 # include <kerberosIV/des.h>
85 #else /* KRB5 */ 88 # else
86 #include <krb5/krb5.h> 89 # ifdef HAVE_KERBEROS_DES_H
87 #include <krb5/ext-proto.h> 90 # include <kerberos/des.h>
88 #include <ctype.h> 91 # endif
89 #endif /* KRB5 */ 92 # endif
93 # endif
94 # ifdef HAVE_KRB_H
95 # include <krb.h>
96 # else
97 # ifdef HAVE_KERBEROSIV_KRB_H
98 # include <kerberosIV/krb.h>
99 # else
100 # ifdef HAVE_KERBEROS_KRB_H
101 # include <kerberos/krb.h>
102 # endif
103 # endif
104 # endif
105 # ifdef HAVE_COM_ERR_H
106 # include <com_err.h>
107 # endif
90 #endif /* KERBEROS */ 108 #endif /* KERBEROS */
109
91 110
92 extern char *getenv (/* char * */); 111 extern char *getenv (/* char * */);
93 extern char *getlogin (/* void */); 112 extern char *getlogin (/* void */);
94 extern char *getpass (/* char * */); 113 extern char *getpass (/* char * */);
95 extern char *strerror (/* int */); 114 extern char *strerror (/* int */);
96 extern char *index (); 115 extern char *index ();
97 116
98 #ifdef KERBEROS 117 #ifdef KERBEROS
99 #ifndef KRB5 118 #ifndef KERBEROS5
100 extern int krb_sendauth (/* long, int, KTEXT, char *, char *, char *, 119 extern int krb_sendauth (/* long, int, KTEXT, char *, char *, char *,
101 u_long, MSG_DAT *, CREDENTIALS *, Key_schedule, 120 u_long, MSG_DAT *, CREDENTIALS *, Key_schedule,
102 struct sockaddr_in *, struct sockaddr_in *, 121 struct sockaddr_in *, struct sockaddr_in *,
103 char * */); 122 char * */);
104 extern char *krb_realmofhost (/* char * */); 123 extern char *krb_realmofhost (/* char * */);
105 #endif /* ! KRB5 */ 124 #endif /* ! KERBEROS5 */
106 #endif /* KERBEROS */ 125 #endif /* KERBEROS */
107 126
108 #ifndef WINDOWSNT 127 #ifndef WINDOWSNT
109 #if !defined(HAVE_H_ERRNO) || !defined(HAVE_CONFIG_H) 128 #if !defined(HAVE_H_ERRNO) || !defined(HAVE_CONFIG_H)
110 extern int h_errno; 129 extern int h_errno;
129 #define POP_SERVICE "pop3" /* we don't want the POP2 port! */ 148 #define POP_SERVICE "pop3" /* we don't want the POP2 port! */
130 #else 149 #else
131 #define POP_SERVICE "pop" 150 #define POP_SERVICE "pop"
132 #endif 151 #endif
133 #ifdef KERBEROS 152 #ifdef KERBEROS
134 #ifdef KRB5
135 #define KPOP_SERVICE "k5pop";
136 #else
137 #define KPOP_SERVICE "kpop" 153 #define KPOP_SERVICE "kpop"
138 #endif
139 #endif 154 #endif
140 155
141 char pop_error[ERROR_MAX]; 156 char pop_error[ERROR_MAX];
142 int pop_debug = 0; 157 int pop_debug = 0;
143 158
991 struct sockaddr_in addr; 1006 struct sockaddr_in addr;
992 char found_port = 0; 1007 char found_port = 0;
993 char *service; 1008 char *service;
994 int sock; 1009 int sock;
995 #ifdef KERBEROS 1010 #ifdef KERBEROS
996 #ifdef KRB5 1011 #ifdef KERBEROS5
997 krb5_error_code rem; 1012 krb5_error_code rem;
1013 krb5_context kcontext = 0;
1014 krb5_auth_context auth_context = 0;
998 krb5_ccache ccdef; 1015 krb5_ccache ccdef;
999 krb5_principal client, server; 1016 krb5_principal client, server;
1000 krb5_error *err_ret; 1017 krb5_error *err_ret;
1001 register char *cp; 1018 register char *cp;
1002 #else 1019 #else
1004 MSG_DAT msg_data; 1021 MSG_DAT msg_data;
1005 CREDENTIALS cred; 1022 CREDENTIALS cred;
1006 Key_schedule schedule; 1023 Key_schedule schedule;
1007 int rem; 1024 int rem;
1008 char *realhost; 1025 char *realhost;
1009 #endif /* KRB5 */ 1026 #endif /* KERBEROS5 */
1010 #endif /* KERBEROS */ 1027 #endif /* KERBEROS */
1011 1028
1012 int try_count = 0; 1029 int try_count = 0;
1013 1030
1014 #ifdef WINDOWSNT 1031 #ifdef WINDOWSNT
1066 addr.sin_port = htons (POP_PORT); 1083 addr.sin_port = htons (POP_PORT);
1067 #endif 1084 #endif
1068 } 1085 }
1069 } 1086 }
1070 1087
1071 #define SOCKET_ERROR "Could not create socket for POP connection: " 1088 #define POP_SOCKET_ERROR "Could not create socket for POP connection: "
1072 1089
1073 sock = socket (PF_INET, SOCK_STREAM, 0); 1090 sock = socket (PF_INET, SOCK_STREAM, 0);
1074 if (sock < 0) 1091 if (sock < 0)
1075 { 1092 {
1076 strcpy (pop_error, SOCKET_ERROR); 1093 strcpy (pop_error, POP_SOCKET_ERROR);
1077 strncat (pop_error, strerror (errno), 1094 strncat (pop_error, strerror (errno),
1078 ERROR_MAX - sizeof (SOCKET_ERROR)); 1095 ERROR_MAX - sizeof (POP_SOCKET_ERROR));
1079 return (-1); 1096 return (-1);
1080 1097
1081 } 1098 }
1082 1099
1083 while (*hostent->h_addr_list) 1100 while (*hostent->h_addr_list)
1103 1120
1104 #ifdef KERBEROS 1121 #ifdef KERBEROS
1105 #define KRB_ERROR "Kerberos error connecting to POP server: " 1122 #define KRB_ERROR "Kerberos error connecting to POP server: "
1106 if (! (flags & POP_NO_KERBEROS)) 1123 if (! (flags & POP_NO_KERBEROS))
1107 { 1124 {
1108 #ifdef KRB5 1125 #ifdef KERBEROS5
1109 krb5_init_ets (); 1126 if ((rem = krb5_init_context (&kcontext)))
1110
1111 if (rem = krb5_cc_default (&ccdef))
1112 { 1127 {
1113 krb5error: 1128 krb5error:
1129 if (auth_context)
1130 krb5_auth_con_free (kcontext, auth_context);
1131 if (kcontext)
1132 krb5_free_context (kcontext);
1114 strcpy (pop_error, KRB_ERROR); 1133 strcpy (pop_error, KRB_ERROR);
1115 strncat (pop_error, error_message (rem), 1134 strncat (pop_error, error_message (rem),
1116 ERROR_MAX - sizeof(KRB_ERROR)); 1135 ERROR_MAX - sizeof(KRB_ERROR));
1117 CLOSESOCKET (sock); 1136 CLOSESOCKET (sock);
1118 return (-1); 1137 return (-1);
1119 } 1138 }
1120 1139
1121 if (rem = krb5_cc_get_principal (ccdef, &client)) 1140 if ((rem = krb5_auth_con_init (kcontext, &auth_context)))
1122 { 1141 goto krb5error;
1123 goto krb5error; 1142
1124 } 1143 if (rem = krb5_cc_default (kcontext, &ccdef))
1144 goto krb5error;
1145
1146 if (rem = krb5_cc_get_principal (kcontext, ccdef, &client))
1147 goto krb5error;
1125 1148
1126 for (cp = hostent->h_name; *cp; cp++) 1149 for (cp = hostent->h_name; *cp; cp++)
1127 { 1150 {
1128 if (isupper (*cp)) 1151 if (isupper (*cp))
1129 { 1152 {
1130 *cp = tolower (*cp); 1153 *cp = tolower (*cp);
1131 } 1154 }
1132 } 1155 }
1133 1156
1134 if (rem = krb5_sname_to_principal (hostent->h_name, POP_SERVICE, 1157 if (rem = krb5_sname_to_principal (kcontext, hostent->h_name,
1135 FALSE, &server)) 1158 POP_SERVICE, FALSE, &server))
1136 { 1159 goto krb5error;
1137 goto krb5error; 1160
1138 } 1161 rem = krb5_sendauth (kcontext, &auth_context,
1139 1162 (krb5_pointer) &sock, "KPOPV1.0", client, server,
1140 rem = krb5_sendauth ((krb5_pointer) &sock, "KPOPV1.0", client, server,
1141 AP_OPTS_MUTUAL_REQUIRED, 1163 AP_OPTS_MUTUAL_REQUIRED,
1142 0, /* no checksum */ 1164 0, /* no checksum */
1143 0, /* no creds, use ccache instead */ 1165 0, /* no creds, use ccache instead */
1144 ccdef, 1166 ccdef,
1145 0, /* don't need seq # */ 1167 &err_ret,
1146 0, /* don't need subsession key */ 1168 0, /* don't need subsession key */
1147 &err_ret,
1148 0); /* don't need reply */ 1169 0); /* don't need reply */
1149 krb5_free_principal (server); 1170 krb5_free_principal (kcontext, server);
1150 if (rem) 1171 if (rem)
1151 { 1172 {
1152 if (err_ret && err_ret->text.length) 1173 if (err_ret && err_ret->text.length)
1153 { 1174 {
1154 strcpy (pop_error, KRB_ERROR); 1175 strcpy (pop_error, KRB_ERROR);
1167 strcpy (pop_error, KRB_ERROR); 1188 strcpy (pop_error, KRB_ERROR);
1168 strncat (pop_error, error_message (rem), 1189 strncat (pop_error, error_message (rem),
1169 ERROR_MAX - sizeof (KRB_ERROR)); 1190 ERROR_MAX - sizeof (KRB_ERROR));
1170 } 1191 }
1171 if (err_ret) 1192 if (err_ret)
1172 krb5_free_error (err_ret); 1193 krb5_free_error (kcontext, err_ret);
1194 krb5_auth_con_free (kcontext, auth_context);
1195 krb5_free_context (kcontext);
1173 1196
1174 CLOSESOCKET (sock); 1197 CLOSESOCKET (sock);
1175 return (-1); 1198 return (-1);
1176 } 1199 }
1177 #else /* ! KRB5 */ 1200 #else /* ! KERBEROS5 */
1178 ticket = (KTEXT) malloc (sizeof (KTEXT_ST)); 1201 ticket = (KTEXT) malloc (sizeof (KTEXT_ST));
1179 realhost = strdup (hostent->h_name); 1202 realhost = strdup (hostent->h_name);
1180 rem = krb_sendauth (0L, sock, ticket, "pop", realhost, 1203 rem = krb_sendauth (0L, sock, ticket, "pop", realhost,
1181 (char *) krb_realmofhost (realhost), 1204 (char *) krb_realmofhost (realhost),
1182 (unsigned long) 0, &msg_data, &cred, schedule, 1205 (unsigned long) 0, &msg_data, &cred, schedule,
1191 strncat (pop_error, krb_err_txt[rem], 1214 strncat (pop_error, krb_err_txt[rem],
1192 ERROR_MAX - sizeof (KRB_ERROR)); 1215 ERROR_MAX - sizeof (KRB_ERROR));
1193 CLOSESOCKET (sock); 1216 CLOSESOCKET (sock);
1194 return (-1); 1217 return (-1);
1195 } 1218 }
1196 #endif /* KRB5 */ 1219 #endif /* KERBEROS5 */
1197 } 1220 }
1198 #endif /* KERBEROS */ 1221 #endif /* KERBEROS */
1199 1222
1200 return (sock); 1223 return (sock);
1201 } /* socket_connection */ 1224 } /* socket_connection */