Mercurial > emacs
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 */ |